summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Lutz <michi@icosahedron.de>2019-03-17 11:05:38 +0100
committerMichael Lutz <michi@icosahedron.de>2019-04-06 11:27:39 +0200
commit94c5269fa772304112b7c40d2c84794056f87717 (patch)
tree0f1eebc855cf74cbedad734e02f19f7b4903567b /src
parent05bc2ed7cbe07cb4cd535932f10778b35f72e944 (diff)
downloadopenttd-94c5269fa772304112b7c40d2c84794056f87717.tar.xz
Codechange: Use atomic variables for thread synchronization where useful.
Diffstat (limited to 'src')
-rw-r--r--src/network/network_gamelist.cpp19
-rw-r--r--src/saveload/saveload.cpp18
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();