summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt3
-rw-r--r--src/common/detached_tasks.cpp41
-rw-r--r--src/common/detached_tasks.h40
-rw-r--r--src/common/web_result.h24
4 files changed, 108 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 6a3f1fe08..8985e4367 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -41,6 +41,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOU
41add_library(common STATIC 41add_library(common STATIC
42 alignment.h 42 alignment.h
43 assert.h 43 assert.h
44 detached_tasks.cpp
45 detached_tasks.h
44 bit_field.h 46 bit_field.h
45 bit_set.h 47 bit_set.h
46 cityhash.cpp 48 cityhash.cpp
@@ -87,6 +89,7 @@ add_library(common STATIC
87 timer.cpp 89 timer.cpp
88 timer.h 90 timer.h
89 vector_math.h 91 vector_math.h
92 web_result.h
90) 93)
91 94
92if(ARCHITECTURE_x86_64) 95if(ARCHITECTURE_x86_64)
diff --git a/src/common/detached_tasks.cpp b/src/common/detached_tasks.cpp
new file mode 100644
index 000000000..a347d9e02
--- /dev/null
+++ b/src/common/detached_tasks.cpp
@@ -0,0 +1,41 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <thread>
6#include "common/assert.h"
7#include "common/detached_tasks.h"
8
9namespace Common {
10
11DetachedTasks* DetachedTasks::instance = nullptr;
12
13DetachedTasks::DetachedTasks() {
14 ASSERT(instance == nullptr);
15 instance = this;
16}
17
18void DetachedTasks::WaitForAllTasks() {
19 std::unique_lock<std::mutex> lock(mutex);
20 cv.wait(lock, [this]() { return count == 0; });
21}
22
23DetachedTasks::~DetachedTasks() {
24 std::unique_lock<std::mutex> lock(mutex);
25 ASSERT(count == 0);
26 instance = nullptr;
27}
28
29void DetachedTasks::AddTask(std::function<void()> task) {
30 std::unique_lock<std::mutex> lock(instance->mutex);
31 ++instance->count;
32 std::thread([task{std::move(task)}]() {
33 task();
34 std::unique_lock<std::mutex> lock(instance->mutex);
35 --instance->count;
36 std::notify_all_at_thread_exit(instance->cv, std::move(lock));
37 })
38 .detach();
39}
40
41} // namespace Common
diff --git a/src/common/detached_tasks.h b/src/common/detached_tasks.h
new file mode 100644
index 000000000..5dd8fc27b
--- /dev/null
+++ b/src/common/detached_tasks.h
@@ -0,0 +1,40 @@
1// Copyright 2018 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <condition_variable>
8#include <functional>
9
10namespace Common {
11
12/**
13 * A background manager which ensures that all detached task is finished before program exits.
14 *
15 * Some tasks, telemetry submission for example, prefer executing asynchronously and don't care
16 * about the result. These tasks are suitable for std::thread::detach(). However, this is unsafe if
17 * the task is launched just before the program exits (which is a common case for telemetry), so we
18 * need to block on these tasks on program exit.
19 *
20 * To make detached task safe, a single DetachedTasks object should be placed in the main(), and
21 * call WaitForAllTasks() after all program execution but before global/static variable destruction.
22 * Any potentially unsafe detached task should be executed via DetachedTasks::AddTask.
23 */
24class DetachedTasks {
25public:
26 DetachedTasks();
27 ~DetachedTasks();
28 void WaitForAllTasks();
29
30 static void AddTask(std::function<void()> task);
31
32private:
33 static DetachedTasks* instance;
34
35 std::condition_variable cv;
36 std::mutex mutex;
37 int count = 0;
38};
39
40} // namespace Common
diff --git a/src/common/web_result.h b/src/common/web_result.h
new file mode 100644
index 000000000..969926674
--- /dev/null
+++ b/src/common/web_result.h
@@ -0,0 +1,24 @@
1// Copyright 2018 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <string>
8
9namespace Common {
10struct WebResult {
11 enum class Code : u32 {
12 Success,
13 InvalidURL,
14 CredentialsMissing,
15 LibError,
16 HttpError,
17 WrongContent,
18 NoWebservice,
19 };
20 Code result_code;
21 std::string result_string;
22 std::string returned_data;
23};
24} // namespace Common