diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/common/detached_tasks.cpp | 41 | ||||
| -rw-r--r-- | src/common/detached_tasks.h | 40 | ||||
| -rw-r--r-- | src/common/web_result.h | 24 |
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 | |||
| 41 | add_library(common STATIC | 41 | add_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 | ||
| 92 | if(ARCHITECTURE_x86_64) | 95 | if(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 | |||
| 9 | namespace Common { | ||
| 10 | |||
| 11 | DetachedTasks* DetachedTasks::instance = nullptr; | ||
| 12 | |||
| 13 | DetachedTasks::DetachedTasks() { | ||
| 14 | ASSERT(instance == nullptr); | ||
| 15 | instance = this; | ||
| 16 | } | ||
| 17 | |||
| 18 | void DetachedTasks::WaitForAllTasks() { | ||
| 19 | std::unique_lock<std::mutex> lock(mutex); | ||
| 20 | cv.wait(lock, [this]() { return count == 0; }); | ||
| 21 | } | ||
| 22 | |||
| 23 | DetachedTasks::~DetachedTasks() { | ||
| 24 | std::unique_lock<std::mutex> lock(mutex); | ||
| 25 | ASSERT(count == 0); | ||
| 26 | instance = nullptr; | ||
| 27 | } | ||
| 28 | |||
| 29 | void 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 | |||
| 10 | namespace 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 | */ | ||
| 24 | class DetachedTasks { | ||
| 25 | public: | ||
| 26 | DetachedTasks(); | ||
| 27 | ~DetachedTasks(); | ||
| 28 | void WaitForAllTasks(); | ||
| 29 | |||
| 30 | static void AddTask(std::function<void()> task); | ||
| 31 | |||
| 32 | private: | ||
| 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 | |||
| 9 | namespace Common { | ||
| 10 | struct 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 | ||