aboutsummaryrefslogtreecommitdiffstats
path: root/src/gpg/GpgFunctionObject.h
diff options
context:
space:
mode:
authorSaturn&Eric <[email protected]>2022-01-05 20:02:19 +0000
committerGitHub <[email protected]>2022-01-05 20:02:19 +0000
commita3ca1bf1d4404327d68d3d49127085638c272152 (patch)
treedeb10c33977e5002fa6e9b434f2b07d2719a4e31 /src/gpg/GpgFunctionObject.h
parentMerge pull request #37 from saturneric/document (diff)
parent<doc>(navbar): take repository and GitHub apart. (diff)
downloadGpgFrontend-a3ca1bf1d4404327d68d3d49127085638c272152.tar.gz
GpgFrontend-a3ca1bf1d4404327d68d3d49127085638c272152.zip
Merge pull request #36 from saturneric/developv2.0.4
v2.0.4
Diffstat (limited to 'src/gpg/GpgFunctionObject.h')
-rw-r--r--src/gpg/GpgFunctionObject.h115
1 files changed, 69 insertions, 46 deletions
diff --git a/src/gpg/GpgFunctionObject.h b/src/gpg/GpgFunctionObject.h
index 6f1d60af..404b2f84 100644
--- a/src/gpg/GpgFunctionObject.h
+++ b/src/gpg/GpgFunctionObject.h
@@ -34,63 +34,61 @@
#include <stdexcept>
#include <string>
+#include "GpgConstants.h"
+
namespace GpgFrontend {
template <typename T>
class SingletonFunctionObject {
public:
- static T& GetInstance(int channel = 0) {
- if (!channel) {
- std::lock_guard<std::mutex> guard(_instance_mutex);
- if (_instance == nullptr) _instance = std::make_unique<T>();
- return *_instance;
- } else {
- // read _instances_map
- decltype(_instances_map.end()) _it;
- {
- std::shared_lock lock(_instances_mutex);
- _it = _instances_map.find(channel);
- }
- if (_it != _instances_map.end())
- return *_it->second;
- else
- return CreateInstance(channel);
- }
+ static T& GetInstance(
+ int channel = GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL) {
+ static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
+ "T not derived from SingletonFunctionObject<T>");
+
+ auto _p_pbj = find_object_in_channel(channel);
+ if (_p_pbj == nullptr)
+ return *set_object_in_channel(channel, std::make_unique<T>(channel));
+ else
+ return *_p_pbj;
+ }
+
+ static T& CreateInstance(int channel,
+ std::function<std::unique_ptr<T>(void)> factory) {
+ static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
+ "T not derived from SingletonFunctionObject<T>");
+
+ auto _p_pbj = find_object_in_channel(channel);
+ if (_p_pbj == nullptr)
+ return *set_object_in_channel(channel, std::move(factory()));
+ else
+ return *_p_pbj;
}
static T& CreateInstance(int channel, std::unique_ptr<T> p_obj = nullptr) {
- if (!channel) return *_instance;
+ static_assert(std::is_base_of<SingletonFunctionObject<T>, T>::value,
+ "T not derived from SingletonFunctionObject<T>");
+
+ auto _p_pbj = find_object_in_channel(channel);
+ if (_p_pbj == nullptr)
+ return *set_object_in_channel(channel, std::move(p_obj));
+ else
+ return *_p_pbj;
+ }
- // read _instances_map
+ static T& ReleaseChannel(int channel) {
decltype(_instances_map.end()) _it;
{
std::shared_lock lock(_instances_mutex);
_it = _instances_map.find(channel);
}
- if (_it == _instances_map.end()) {
- {
- std::lock_guard<std::mutex> guard(_default_channel_mutex);
- int tmp = channel;
- std::swap(_default_channel, tmp);
- if (p_obj == nullptr) p_obj = std::make_unique<T>();
- std::swap(_default_channel, tmp);
- }
- T* obj = p_obj.get();
-
- // change _instances_map
- {
- std::unique_lock lock(_instances_mutex);
- _instances_map.insert({channel, std::move(p_obj)});
- }
- return *obj;
- } else {
- return *_it->second;
- }
+ if (_it != _instances_map.end()) _instances_map.erase(_it);
+ DLOG(INFO) << "channel" << channel << "released";
}
static int GetDefaultChannel() { return _default_channel; }
- int GetChannel() const { return channel_; }
+ [[nodiscard]] int GetChannel() const { return channel_; }
SingletonFunctionObject(T&&) = delete;
@@ -99,27 +97,52 @@ class SingletonFunctionObject {
void operator=(const T&) = delete;
protected:
- SingletonFunctionObject() {}
+ SingletonFunctionObject() = default;
- SingletonFunctionObject(int channel) : channel_(channel) {}
+ explicit SingletonFunctionObject(int channel) : channel_(channel) {}
virtual ~SingletonFunctionObject() = default;
+ void SetChannel(int channel) { this->channel_ = channel; }
+
private:
int channel_ = _default_channel;
static int _default_channel;
- static std::mutex _default_channel_mutex;
static std::mutex _instance_mutex;
static std::shared_mutex _instances_mutex;
static std::unique_ptr<T> _instance;
static std::map<int, std::unique_ptr<T>> _instances_map;
-};
-template <typename T>
-int SingletonFunctionObject<T>::_default_channel = 0;
+ static T* find_object_in_channel(int channel) {
+ // read _instances_map
+ decltype(_instances_map.end()) _it;
+ {
+ std::shared_lock lock(_instances_mutex);
+ _it = _instances_map.find(channel);
+ if (_it == _instances_map.end())
+ return nullptr;
+ else
+ return _it->second.get();
+ }
+ }
+
+ static T* set_object_in_channel(int channel, std::unique_ptr<T> p_obj) {
+ {
+ if (p_obj == nullptr) p_obj = std::make_unique<T>();
+ T* obj = p_obj.get();
+ obj->SetChannel(channel);
+ {
+ std::unique_lock lock(_instances_mutex);
+ _instances_map.insert({channel, std::move(p_obj)});
+ }
+ return obj;
+ }
+ }
+};
template <typename T>
-std::mutex SingletonFunctionObject<T>::_default_channel_mutex;
+int SingletonFunctionObject<T>::_default_channel =
+ GpgFrontend::GPGFRONTEND_DEFAULT_CHANNEL;
template <typename T>
std::mutex SingletonFunctionObject<T>::_instance_mutex;