aboutsummaryrefslogtreecommitdiffstats
path: root/src/core/function/basic
diff options
context:
space:
mode:
authorsaturneric <[email protected]>2023-12-15 13:14:17 +0000
committersaturneric <[email protected]>2023-12-15 13:14:17 +0000
commitf9a49043c35e73fc2d4ffb3ed9b39c33849c43b3 (patch)
tree7e03b0b62119ff5d5dcd732ec1ccb7d2296df86d /src/core/function/basic
parentfix: slove some issues on memory and intilizations (diff)
downloadGpgFrontend-f9a49043c35e73fc2d4ffb3ed9b39c33849c43b3.tar.gz
GpgFrontend-f9a49043c35e73fc2d4ffb3ed9b39c33849c43b3.zip
fix: slove threading and memory issues
Diffstat (limited to 'src/core/function/basic')
-rw-r--r--src/core/function/basic/GpgFunctionObject.cpp78
-rw-r--r--src/core/function/basic/GpgFunctionObject.h86
-rw-r--r--src/core/function/basic/SingletonStorage.cpp49
3 files changed, 126 insertions, 87 deletions
diff --git a/src/core/function/basic/GpgFunctionObject.cpp b/src/core/function/basic/GpgFunctionObject.cpp
index 242621d2..e31ff2d6 100644
--- a/src/core/function/basic/GpgFunctionObject.cpp
+++ b/src/core/function/basic/GpgFunctionObject.cpp
@@ -26,4 +26,80 @@
*
*/
-#include "GpgFunctionObject.h" \ No newline at end of file
+#include "GpgFunctionObject.h"
+
+#include <map>
+#include <mutex>
+#include <typeinfo>
+
+#include "function/SecureMemoryAllocator.h"
+#include "function/basic/ChannelObject.h"
+
+struct FunctionObjectTypeLockInfo {
+ std::map<int, std::mutex> channel_lock_map;
+ std::mutex type_lock;
+};
+
+std::mutex g_function_object_mutex_map_lock;
+std::map<size_t, FunctionObjectTypeLockInfo> g_function_object_mutex_map;
+
+namespace GpgFrontend {
+auto GetGlobalFunctionObjectChannelLock(const std::type_info& type, int channel)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.channel_lock_map[channel];
+}
+
+auto GetGlobalFunctionObjectTypeLock(const std::type_info& type)
+ -> std::mutex& {
+ std::lock_guard<std::mutex> lock_guard(g_function_object_mutex_map_lock);
+ auto& channel_map = g_function_object_mutex_map[type.hash_code()];
+ return channel_map.type_lock;
+}
+
+/**
+ * @brief Get the Instance object
+ *
+ * @param channel
+ * @return T&
+ */
+auto GetChannelObjectInstance(const std::type_info& type, int channel)
+ -> ChannelObject* {
+ SPDLOG_TRACE("try to get instance of type: {} at channel: {}", type.name(),
+ channel);
+
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ SPDLOG_TRACE("get singleton storage result, p_storage: {}",
+ static_cast<void*>(p_storage));
+
+ auto* p_pbj =
+ static_cast<ChannelObject*>(p_storage->FindObjectInChannel(channel));
+ SPDLOG_TRACE("find channel object result, channel {}, p_pbj: {}", channel,
+ static_cast<void*>(p_pbj));
+
+ return p_pbj;
+}
+
+auto CreateChannelObjectInstance(const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object)
+ -> ChannelObject* {
+ // lock this channel
+ std::lock_guard<std::mutex> guard(
+ GetGlobalFunctionObjectChannelLock(type, channel));
+
+ auto* p_storage =
+ SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(type);
+ SPDLOG_TRACE("create channel object, channel {}, type: {}", channel,
+ type.name());
+
+ // do create object of this channel
+ return p_storage->SetObjectInChannel(channel, std::move(channel_object));
+}
+
+} // namespace GpgFrontend \ No newline at end of file
diff --git a/src/core/function/basic/GpgFunctionObject.h b/src/core/function/basic/GpgFunctionObject.h
index afe81131..1ea352b6 100644
--- a/src/core/function/basic/GpgFunctionObject.h
+++ b/src/core/function/basic/GpgFunctionObject.h
@@ -28,14 +28,27 @@
#pragma once
+#include <mutex>
+#include <stdexcept>
+
+#include "core/GpgFrontendCoreExport.h"
#include "core/function/basic/ChannelObject.h"
#include "core/function/basic/SingletonStorage.h"
#include "core/function/basic/SingletonStorageCollection.h"
#include "core/utils/MemoryUtils.h"
-#include "spdlog/spdlog.h"
namespace GpgFrontend {
+auto GPGFRONTEND_CORE_EXPORT GetChannelObjectInstance(
+ const std::type_info& type, int channel) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT CreateChannelObjectInstance(
+ const std::type_info& type, int channel,
+ SecureUniquePtr<ChannelObject> channel_object) -> ChannelObject*;
+
+auto GPGFRONTEND_CORE_EXPORT
+GetGlobalFunctionObjectTypeLock(const std::type_info& type) -> std::mutex&;
+
/**
* @brief
*
@@ -66,52 +79,18 @@ class SingletonFunctionObject : public ChannelObject {
*/
static auto GetInstance(int channel = GpgFrontend::kGpgFrontendDefaultChannel)
-> T& {
- static std::mutex g_channel_mutex_map_lock;
- static std::map<int, std::mutex> g_channel_mutex_map;
-
- SPDLOG_TRACE("try to get instance of type: {} at channel: {}",
- typeid(T).name(), channel);
-
- {
- 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_v<SingletonFunctionObject<T>, T>,
"T not derived from SingletonFunctionObject<T>");
- auto* p_storage =
- SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
- typeid(T));
- SPDLOG_TRACE("get singleton storage result, p_storage: {}",
- static_cast<void*>(p_storage));
-
- auto* p_pbj = static_cast<T*>(p_storage->FindObjectInChannel(channel));
- SPDLOG_TRACE("find channel object result, channel {}, p_pbj: {}", channel,
- static_cast<void*>(p_pbj));
-
- if (p_pbj == nullptr) {
- SPDLOG_TRACE("create channel object, channel {}, type: {}", channel,
- typeid(T).name());
-
- // lock this channel
- std::lock_guard<std::mutex> guard(g_channel_mutex_map[channel]);
-
- // double check
- if (p_pbj = static_cast<T*>(p_storage->FindObjectInChannel(channel));
- p_pbj != nullptr) {
- return *p_pbj;
- }
-
- // do create object of this channel
- auto new_obj =
- ConvertToChannelObjectPtr<>(SecureCreateUniqueObject<T>(channel));
- return *static_cast<T*>(
- p_storage->SetObjectInChannel(channel, std::move(new_obj)));
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ auto* channel_object = GetChannelObjectInstance(type, channel);
+ if (channel_object == nullptr) {
+ channel_object = CreateChannelObjectInstance(
+ type, channel,
+ ConvertToChannelObjectPtr(SecureCreateUniqueObject<T>(channel)));
}
- return *p_pbj;
+ return *static_cast<T*>(channel_object);
}
/**
@@ -126,23 +105,10 @@ class SingletonFunctionObject : public ChannelObject {
static_assert(std::is_base_of_v<SingletonFunctionObject<T>, T>,
"T not derived from SingletonFunctionObject<T>");
- auto* p_storage =
- SingletonStorageCollection::GetInstance(false)->GetSingletonStorage(
- typeid(T));
- SPDLOG_TRACE("get singleton storage result, p_storage: {}",
- static_cast<void*>(p_storage));
-
- auto p_pbj = static_cast<T*>(p_storage->FindObjectInChannel(channel));
- SPDLOG_TRACE("find channel object result, channel {}, p_pbj: {}", channel,
- static_cast<void*>(p_pbj));
-
- if (p_pbj == nullptr) {
- SPDLOG_TRACE("create channel object, channel {}, type: {}", channel,
- typeid(T).name());
- return *static_cast<T*>(
- p_storage->SetObjectInChannel(channel, factory()));
- }
- return *p_pbj;
+ const auto& type = typeid(T);
+ std::lock_guard<std::mutex> guard(GetGlobalFunctionObjectTypeLock(type));
+ return *static_cast<T*>(
+ CreateChannelObjectInstance(type, channel, factory()));
}
/**
diff --git a/src/core/function/basic/SingletonStorage.cpp b/src/core/function/basic/SingletonStorage.cpp
index 4786ad93..73e19ddd 100644
--- a/src/core/function/basic/SingletonStorage.cpp
+++ b/src/core/function/basic/SingletonStorage.cpp
@@ -52,7 +52,7 @@ class SingletonStorage::Impl {
std::shared_lock<std::shared_mutex> lock(instances_mutex_);
ins_it = instances_map_.find(channel);
if (ins_it == instances_map_.end()) {
- SPDLOG_TRACE("cannot find channel object, channel :{}", channel);
+ SPDLOG_TRACE("cannot find channel object, channel: {}", channel);
return nullptr;
}
return ins_it->second.get();
@@ -70,35 +70,32 @@ class SingletonStorage::Impl {
auto SetObjectInChannel(int channel, ChannelObjectPtr p_obj)
-> GpgFrontend::ChannelObject* {
- {
- SPDLOG_TRACE("set channel object, type: {} in channel: {}, address: {}",
- typeid(p_obj.get()).name(), channel,
- static_cast<void*>(p_obj.get()));
-
- assert(p_obj != nullptr);
- if (p_obj == nullptr) {
- SPDLOG_ERROR("cannot set a nullptr as a channel obejct of channel: {}",
- channel);
- return nullptr;
- }
-
- p_obj->SetChannel(channel);
- auto* raw_obj = p_obj.get();
+ SPDLOG_TRACE("set channel object, type: {} in channel: {}, address: {}",
+ typeid(p_obj.get()).name(), channel,
+ static_cast<void*>(p_obj.get()));
+
+ assert(p_obj != nullptr);
+ if (p_obj == nullptr) {
+ SPDLOG_ERROR("cannot set a nullptr as a channel obejct of channel: {}",
+ channel);
+ return nullptr;
+ }
- {
- SPDLOG_TRACE(
- "register channel object to instances map, "
- "channel: {}, address: {}",
- channel, static_cast<void*>(p_obj.get()));
- std::unique_lock<std::shared_mutex> lock(instances_mutex_);
- instances_map_[channel] = std::move(p_obj);
- }
+ p_obj->SetChannel(channel);
+ auto* raw_obj = p_obj.get();
+ {
SPDLOG_TRACE(
- "set channel: {} success, current channel object address: {}",
- channel, static_cast<void*>(raw_obj));
- return raw_obj;
+ "register channel object to instances map, "
+ "channel: {}, address: {}",
+ channel, static_cast<void*>(p_obj.get()));
+ std::unique_lock<std::shared_mutex> lock(instances_mutex_);
+ instances_map_[channel] = std::move(p_obj);
}
+
+ SPDLOG_TRACE("set channel: {} success, current channel object address: {}",
+ channel, static_cast<void*>(raw_obj));
+ return raw_obj;
}
private: