summaryrefslogtreecommitdiff
path: root/Source/Core/Common/Config/Config.cpp
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2025-04-26 11:13:44 +0200
committerJosJuice <josjuice@gmail.com>2025-04-26 12:56:37 +0200
commitf060baa2572d60a4c4e61f3cf730070f77f4f472 (patch)
tree7dda961b905afd4743301a7d4f8b65c3bde0410d /Source/Core/Common/Config/Config.cpp
parent805307f432dba079caf7339122a07de5b90c4b47 (diff)
Config: Add locking for config changed callbacks
Different threads are adding and calling callbacks, so this should have some locking. This is both to ensure thread safety when accessing `s_callbacks` and to ensure that there won't be situations where a callback gets called after it's removed. `s_callback_guards` is also accessed from multiple threads and has therefore been made atomic.
Diffstat (limited to 'Source/Core/Common/Config/Config.cpp')
-rw-r--r--Source/Core/Common/Config/Config.cpp7
1 files changed, 6 insertions, 1 deletions
diff --git a/Source/Core/Common/Config/Config.cpp b/Source/Core/Common/Config/Config.cpp
index b1e591ddac..b5aefc0e9d 100644
--- a/Source/Core/Common/Config/Config.cpp
+++ b/Source/Core/Common/Config/Config.cpp
@@ -20,10 +20,11 @@ using Layers = std::map<LayerType, std::shared_ptr<Layer>>;
static Layers s_layers;
static std::vector<std::pair<ConfigChangedCallbackID, ConfigChangedCallback>> s_callbacks;
static size_t s_next_callback_id = 0;
-static u32 s_callback_guards = 0;
+static std::atomic<u32> s_callback_guards = 0;
static std::atomic<u64> s_config_version = 0;
static std::shared_mutex s_layers_rw_lock;
+static std::mutex s_callbacks_lock;
using ReadLock = std::shared_lock<std::shared_mutex>;
using WriteLock = std::unique_lock<std::shared_mutex>;
@@ -69,6 +70,7 @@ void RemoveLayer(LayerType layer)
ConfigChangedCallbackID AddConfigChangedCallback(ConfigChangedCallback func)
{
+ std::lock_guard lock(s_callbacks_lock);
const ConfigChangedCallbackID callback_id{s_next_callback_id};
++s_next_callback_id;
s_callbacks.emplace_back(std::make_pair(callback_id, std::move(func)));
@@ -77,6 +79,7 @@ ConfigChangedCallbackID AddConfigChangedCallback(ConfigChangedCallback func)
void RemoveConfigChangedCallback(ConfigChangedCallbackID callback_id)
{
+ std::lock_guard lock(s_callbacks_lock);
for (auto it = s_callbacks.begin(); it != s_callbacks.end(); ++it)
{
if (it->first == callback_id)
@@ -97,6 +100,8 @@ void OnConfigChanged()
if (s_callback_guards)
return;
+ std::lock_guard lock(s_callbacks_lock);
+
for (const auto& callback : s_callbacks)
callback.second();
}