diff options
-rw-r--r-- | src/network/network_gamelist.cpp | 19 | ||||
-rw-r--r-- | src/saveload/saveload.cpp | 18 |
2 files changed, 17 insertions, 20 deletions
diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index c67fba5ec..e9fc5f943 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -18,16 +18,14 @@ #include "network_internal.h" #include "network_udp.h" #include "network_gamelist.h" -#include <mutex> +#include <atomic> #include "../safeguards.h" NetworkGameList *_network_game_list = NULL; -/** Mutex for handling delayed insertion/querying of servers. */ -static std::mutex _network_game_list_mutex; /** The games to insert when the GUI thread has time for us. */ -static NetworkGameList *_network_game_delayed_insertion_list = NULL; +static std::atomic<NetworkGameList *> _network_game_delayed_insertion_list(NULL); /** * Add a new item to the linked gamelist, but do it delayed in the next tick @@ -36,18 +34,17 @@ static NetworkGameList *_network_game_delayed_insertion_list = NULL; */ void NetworkGameListAddItemDelayed(NetworkGameList *item) { - std::lock_guard<std::mutex> lock(_network_game_list_mutex); - item->next = _network_game_delayed_insertion_list; - _network_game_delayed_insertion_list = item; + item->next = _network_game_delayed_insertion_list.load(std::memory_order_relaxed); + while (!_network_game_delayed_insertion_list.compare_exchange_weak(item->next, item, std::memory_order_acq_rel)) {} } /** Perform the delayed (thread safe) insertion into the game list */ static void NetworkGameListHandleDelayedInsert() { - std::lock_guard<std::mutex> lock(_network_game_list_mutex); - while (_network_game_delayed_insertion_list != NULL) { - NetworkGameList *ins_item = _network_game_delayed_insertion_list; - _network_game_delayed_insertion_list = ins_item->next; + while (true) { + NetworkGameList *ins_item = _network_game_delayed_insertion_list.load(std::memory_order_relaxed); + while (ins_item != NULL && !_network_game_delayed_insertion_list.compare_exchange_weak(ins_item, ins_item->next, std::memory_order_acq_rel)) {} + if (ins_item == NULL) break; // No item left. NetworkGameList *item = NetworkGameListAddItem(ins_item->address); diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 95690f6af..721631fe6 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -45,6 +45,7 @@ #include "../string_func.h" #include "../fios.h" #include "../error.h" +#include <atomic> #include "table/strings.h" @@ -370,9 +371,9 @@ void NORETURN SlErrorCorruptFmt(const char *format, ...) } -typedef void (*AsyncSaveFinishProc)(); ///< Callback for when the savegame loading is finished. -static AsyncSaveFinishProc _async_save_finish = NULL; ///< Callback to call when the savegame loading is finished. -static std::thread _save_thread; ///< The thread we're using to compress and write a savegame +typedef void (*AsyncSaveFinishProc)(); ///< Callback for when the savegame loading is finished. +static std::atomic<AsyncSaveFinishProc> _async_save_finish; ///< Callback to call when the savegame loading is finished. +static std::thread _save_thread; ///< The thread we're using to compress and write a savegame /** * Called by save thread to tell we finished saving. @@ -381,9 +382,9 @@ static std::thread _save_thread; ///< The thread we're usin static void SetAsyncSaveFinish(AsyncSaveFinishProc proc) { if (_exit_game) return; - while (_async_save_finish != NULL) CSleep(10); + while (_async_save_finish.load(std::memory_order_acquire) != NULL) CSleep(10); - _async_save_finish = proc; + _async_save_finish.store(proc, std::memory_order_release); } /** @@ -391,11 +392,10 @@ static void SetAsyncSaveFinish(AsyncSaveFinishProc proc) */ void ProcessAsyncSaveFinish() { - if (_async_save_finish == NULL) return; - - _async_save_finish(); + AsyncSaveFinishProc proc = _async_save_finish.exchange(NULL, std::memory_order_acq_rel); + if (proc == NULL) return; - _async_save_finish = NULL; + proc(); if (_save_thread.joinable()) { _save_thread.join(); |