summaryrefslogtreecommitdiffstats
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.h39
-rw-r--r--src/common/web_result.h24
4 files changed, 107 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
add_library(common STATIC
alignment.h
assert.h
+ detached_tasks.cpp
+ detached_tasks.h
bit_field.h
bit_set.h
cityhash.cpp
@@ -87,6 +89,7 @@ add_library(common STATIC
timer.cpp
timer.h
vector_math.h
+ web_result.h
)
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 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <thread>
+#include "common/assert.h"
+#include "common/detached_tasks.h"
+
+namespace Common {
+
+DetachedTasks* DetachedTasks::instance = nullptr;
+
+DetachedTasks::DetachedTasks() {
+ ASSERT(instance == nullptr);
+ instance = this;
+}
+
+void DetachedTasks::WaitForAllTasks() {
+ std::unique_lock<std::mutex> lock(mutex);
+ cv.wait(lock, [this]() { return count == 0; });
+}
+
+DetachedTasks::~DetachedTasks() {
+ std::unique_lock<std::mutex> lock(mutex);
+ ASSERT(count == 0);
+ instance = nullptr;
+}
+
+void DetachedTasks::AddTask(std::function<void()> task) {
+ std::unique_lock<std::mutex> lock(instance->mutex);
+ ++instance->count;
+ std::thread([task{std::move(task)}]() {
+ task();
+ std::unique_lock<std::mutex> lock(instance->mutex);
+ --instance->count;
+ std::notify_all_at_thread_exit(instance->cv, std::move(lock));
+ })
+ .detach();
+}
+
+} // namespace Common
diff --git a/src/common/detached_tasks.h b/src/common/detached_tasks.h
new file mode 100644
index 000000000..eae27788d
--- /dev/null
+++ b/src/common/detached_tasks.h
@@ -0,0 +1,39 @@
+// Copyright 2018 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+#include <condition_variable>
+#include <functional>
+
+namespace Common {
+
+/**
+ * A background manager which ensures that all detached task is finished before program exits.
+ *
+ * Some tasks, telemetry submission for example, prefer executing asynchronously and don't care
+ * about the result. These tasks are suitable for std::thread::detach(). However, this is unsafe if
+ * the task is launched just before the program exits (which is a common case for telemetry), so we
+ * need to block on these tasks on program exit.
+ *
+ * To make detached task safe, a single DetachedTasks object should be placed in the main(), and
+ * call WaitForAllTasks() after all program execution but before global/static variable destruction.
+ * Any potentially unsafe detached task should be executed via DetachedTasks::AddTask.
+ */
+class DetachedTasks {
+public:
+ DetachedTasks();
+ ~DetachedTasks();
+ void WaitForAllTasks();
+
+ static void AddTask(std::function<void()> task);
+
+private:
+ static DetachedTasks* instance;
+
+ std::condition_variable cv;
+ std::mutex mutex;
+ int count = 0;
+};
+
+} // namespace Common
diff --git a/src/common/web_result.h b/src/common/web_result.h
new file mode 100644
index 000000000..13610a7ea
--- /dev/null
+++ b/src/common/web_result.h
@@ -0,0 +1,24 @@
+// Copyright 2018 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <string>
+
+namespace Common {
+struct WebResult {
+ enum class Code : u32 {
+ Success,
+ InvalidURL,
+ CredentialsMissing,
+ LibError,
+ HttpError,
+ WrongContent,
+ NoWebservice,
+ };
+ Code result_code;
+ std::string result_string;
+ std::string returned_data;
+};
+} // namespace Commo \ No newline at end of file