aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/GpgFunctionObject.h
diff options
context:
space:
mode:
authorSaturn&Eric <[email protected]>2023-02-25 11:49:54 +0000
committerGitHub <[email protected]>2023-02-25 11:49:54 +0000
commitaf1cd680f2496629026ba27707cef2afd860f5f9 (patch)
tree78e78450893e98b8828cc41010e377c1561e5f34 /src/core/GpgFunctionObject.h
parentfix: improve manual (diff)
parentfeat: use aqt to install qt in ci build (diff)
downloadGpgFrontend-af1cd680f2496629026ba27707cef2afd860f5f9.tar.gz
GpgFrontend-af1cd680f2496629026ba27707cef2afd860f5f9.zip
Merge pull request #91 from saturneric/dev/2.0.10/main
Develop 2.1.0.1
Diffstat (limited to '')
-rw-r--r--src/core/GpgFunctionObject.h23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/core/GpgFunctionObject.h b/src/core/GpgFunctionObject.h
index 56d0ab22..9b8c2aa3 100644
--- a/src/core/GpgFunctionObject.h
+++ b/src/core/GpgFunctionObject.h
@@ -29,6 +29,8 @@
#ifndef GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
#define GPGFRONTEND_ZH_CN_TS_FUNCTIONOBJECT_H
+#include <mutex>
+
#include "GpgConstants.h"
namespace GpgFrontend {
@@ -169,16 +171,33 @@ class SingletonFunctionObject : public ChannelObject {
*/
static T& GetInstance(
int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) {
+ static std::mutex g_channel_mutex_map_lock;
+ static std::map<int, std::mutex> g_channel_mutex_map;
+
+ {
+ std::lock_guard<std::mutex> guard(g_channel_mutex_map_lock);
+ if (g_channel_mutex_map.find(channel) == g_channel_mutex_map.end()) {
+ g_channel_mutex_map[channel];
+ }
+ }
+
static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
"T not derived from SingletonFunctionObject<T>");
- auto p_storage =
+ auto* p_storage =
SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
typeid(T));
-
auto* _p_pbj = (T*)(p_storage->FindObjectInChannel(channel));
if (_p_pbj == nullptr) {
+ // lock this channel
+ std::lock_guard<std::mutex> guard(g_channel_mutex_map[channel]);
+
+ // double check
+ if ((_p_pbj = (T*)(p_storage->FindObjectInChannel(channel))) != nullptr)
+ return *_p_pbj;
+
+ // do create object of this channel
auto new_obj = std::unique_ptr<ChannelObject>(new T(channel));
return *(T*)(p_storage->SetObjectInChannel(channel, std::move(new_obj)));
} else {