mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Merge pull request #4211 from wwylele/web-cleanup
web_service: stop using std::future + callback style async
This commit is contained in:
		
						commit
						4a30a502a0
					
				
					 23 changed files with 333 additions and 458 deletions
				
			
		|  | @ -42,6 +42,8 @@ add_library(common STATIC | |||
|     alignment.h | ||||
|     announce_multiplayer_room.h | ||||
|     assert.h | ||||
|     detached_tasks.cpp | ||||
|     detached_tasks.h | ||||
|     bit_field.h | ||||
|     bit_set.h | ||||
|     chunk_file.h | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
| 
 | ||||
| #include <array> | ||||
| #include <functional> | ||||
| #include <future> | ||||
| #include <string> | ||||
| #include <vector> | ||||
| #include "common/common_types.h" | ||||
|  | @ -90,7 +89,7 @@ public: | |||
|      * Send the data to the announce service | ||||
|      * @result The result of the announce attempt | ||||
|      */ | ||||
|     virtual std::future<Common::WebResult> Announce() = 0; | ||||
|     virtual Common::WebResult Announce() = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Empties the stored players | ||||
|  | @ -99,11 +98,9 @@ public: | |||
| 
 | ||||
|     /**
 | ||||
|      * Get the room information from the announce service | ||||
|      * @param func a function that gets exectued when the get finished. | ||||
|      * Can be used as a callback | ||||
|      * @result A list of all rooms the announce service has | ||||
|      */ | ||||
|     virtual std::future<RoomList> GetRoomList(std::function<void()> func) = 0; | ||||
|     virtual RoomList GetRoomList() = 0; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Sends a delete message to the announce service | ||||
|  | @ -124,18 +121,12 @@ public: | |||
|                             const u64 /*preferred_game_id*/) override {} | ||||
|     void AddPlayer(const std::string& /*nickname*/, const MacAddress& /*mac_address*/, | ||||
|                    const u64 /*game_id*/, const std::string& /*game_name*/) override {} | ||||
|     std::future<Common::WebResult> Announce() override { | ||||
|         return std::async(std::launch::deferred, []() { | ||||
|             return Common::WebResult{Common::WebResult::Code::NoWebservice, | ||||
|                                      "WebService is missing"}; | ||||
|         }); | ||||
|     Common::WebResult Announce() override { | ||||
|         return Common::WebResult{Common::WebResult::Code::NoWebservice, "WebService is missing"}; | ||||
|     } | ||||
|     void ClearPlayers() override {} | ||||
|     std::future<RoomList> GetRoomList(std::function<void()> func) override { | ||||
|         return std::async(std::launch::deferred, [func]() { | ||||
|             func(); | ||||
|             return RoomList{}; | ||||
|         }); | ||||
|     RoomList GetRoomList() override { | ||||
|         return RoomList{}; | ||||
|     } | ||||
| 
 | ||||
|     void Delete() override {} | ||||
|  |  | |||
							
								
								
									
										41
									
								
								src/common/detached_tasks.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/common/detached_tasks.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||
							
								
								
									
										39
									
								
								src/common/detached_tasks.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/common/detached_tasks.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -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
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue