File indexing completed on 2025-01-18 09:57:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #pragma once
0026
0027 #include <atomic>
0028 #include <functional>
0029 #include <memory>
0030 #include <mutex>
0031 #include <set>
0032 #include <thread>
0033 #include <type_traits>
0034
0035 namespace PTL
0036 {
0037
0038
0039
0040 template <typename Type,
0041 typename PointerT = std::unique_ptr<Type, std::default_delete<Type>>>
0042 class Singleton
0043 {
0044 public:
0045 using this_type = Singleton<Type, PointerT>;
0046 using thread_id_t = std::thread::id;
0047 using mutex_t = std::recursive_mutex;
0048 using auto_lock_t = std::unique_lock<mutex_t>;
0049 using pointer = Type*;
0050 using list_t = std::set<pointer>;
0051 using smart_pointer = PointerT;
0052 using deleter_t = std::function<void(PointerT&)>;
0053
0054 template <bool B, typename T = int>
0055 using enable_if_t = typename std::enable_if<B, T>::type;
0056
0057 public:
0058
0059 Singleton();
0060 Singleton(pointer);
0061 ~Singleton();
0062
0063 Singleton(const Singleton&) = delete;
0064 Singleton(Singleton&&) = delete;
0065 Singleton& operator=(const Singleton&) = delete;
0066 Singleton& operator=(Singleton&&) = delete;
0067
0068 public:
0069
0070 static pointer GetInstance();
0071 static pointer GetMasterInstance();
0072 static thread_id_t GetMasterThreadID() { return f_master_thread(); }
0073 static list_t Children() { return f_children(); }
0074 static bool IsMaster(pointer ptr) { return ptr == GetRawMasterInstance(); }
0075 static bool IsMasterThread();
0076 static void Insert(pointer);
0077 static void Remove(pointer);
0078 static mutex_t& GetMutex() { return f_mutex(); }
0079
0080 public:
0081
0082 void Initialize();
0083 void Initialize(pointer);
0084 void Destroy();
0085 void Reset(pointer);
0086 void Reset();
0087
0088
0089 void* operator new(size_t)
0090 {
0091 this_type* ptr = ::new this_type();
0092 return static_cast<void*>(ptr);
0093 }
0094
0095
0096
0097 void operator delete(void* ptr)
0098 {
0099 this_type* _instance = (this_type*) (ptr);
0100 ::delete _instance;
0101 if(std::this_thread::get_id() == f_master_thread())
0102 f_master_instance() = nullptr;
0103 }
0104
0105 protected:
0106 friend class Type;
0107
0108
0109 smart_pointer& GetSmartInstance() { return _local_instance(); }
0110 static smart_pointer& GetSmartMasterInstance() { return _master_instance(); }
0111
0112
0113 pointer GetRawInstance()
0114 {
0115 return IsMasterThread() ? f_master_instance() : _local_instance().get();
0116 }
0117 static pointer GetRawMasterInstance() { return f_master_instance(); }
0118
0119 private:
0120
0121 static smart_pointer& _local_instance()
0122 {
0123 static thread_local smart_pointer _instance = smart_pointer();
0124 return _instance;
0125 }
0126
0127 static smart_pointer& _master_instance()
0128 {
0129 static smart_pointer _instance = smart_pointer();
0130 return _instance;
0131 }
0132
0133 void* operator new[](std::size_t) noexcept { return nullptr; }
0134 void operator delete[](void*) noexcept {}
0135
0136 template <typename Tp = Type, typename PtrT = PointerT,
0137 enable_if_t<(std::is_same<PtrT, std::shared_ptr<Tp>>::value)> = 0>
0138 deleter_t& GetDeleter()
0139 {
0140 static deleter_t _instance = [](PointerT&) {};
0141 return _instance;
0142 }
0143
0144 template <typename Tp = Type, typename PtrT = PointerT,
0145 enable_if_t<!(std::is_same<PtrT, std::shared_ptr<Tp>>::value)> = 0>
0146 deleter_t& GetDeleter()
0147 {
0148 static deleter_t _instance = [](PointerT& _master) {
0149 auto& del = _master.get_deleter();
0150 del(_master.get());
0151 _master.reset(nullptr);
0152 };
0153 return _instance;
0154 }
0155
0156 private:
0157
0158 struct persistent_data
0159 {
0160 thread_id_t m_master_thread = std::this_thread::get_id();
0161 mutex_t m_mutex;
0162 pointer m_master_instance = nullptr;
0163 list_t m_children = {};
0164
0165 persistent_data() = default;
0166 ~persistent_data() = default;
0167 persistent_data(const persistent_data&) = delete;
0168 persistent_data(persistent_data&&) = delete;
0169 persistent_data& operator=(const persistent_data&) = delete;
0170 persistent_data& operator=(persistent_data&&) = delete;
0171
0172 persistent_data(pointer _master, std::thread::id _tid)
0173 : m_master_thread(_tid)
0174 , m_master_instance(_master)
0175 {}
0176
0177 void reset()
0178 {
0179 m_master_instance = nullptr;
0180 m_children.clear();
0181 }
0182 };
0183
0184 bool m_IsMaster = false;
0185 static thread_id_t& f_master_thread();
0186 static mutex_t& f_mutex();
0187 static pointer& f_master_instance();
0188 static list_t& f_children();
0189
0190 static persistent_data& f_persistent_data()
0191 {
0192 static persistent_data _instance;
0193 return _instance;
0194 }
0195 };
0196
0197
0198
0199 template <typename Type, typename PointerT>
0200 typename Singleton<Type, PointerT>::thread_id_t&
0201 Singleton<Type, PointerT>::f_master_thread()
0202 {
0203 return f_persistent_data().m_master_thread;
0204 }
0205
0206
0207
0208 template <typename Type, typename PointerT>
0209 typename Singleton<Type, PointerT>::pointer&
0210 Singleton<Type, PointerT>::f_master_instance()
0211 {
0212 return f_persistent_data().m_master_instance;
0213 }
0214
0215
0216
0217 template <typename Type, typename PointerT>
0218 typename Singleton<Type, PointerT>::mutex_t&
0219 Singleton<Type, PointerT>::f_mutex()
0220 {
0221 return f_persistent_data().m_mutex;
0222 }
0223
0224
0225
0226 template <typename Type, typename PointerT>
0227 typename Singleton<Type, PointerT>::list_t&
0228 Singleton<Type, PointerT>::f_children()
0229 {
0230 return f_persistent_data().m_children;
0231 }
0232
0233
0234
0235 template <typename Type, typename PointerT>
0236 Singleton<Type, PointerT>::Singleton()
0237 {
0238 Initialize();
0239 }
0240
0241
0242
0243 template <typename Type, typename PointerT>
0244 Singleton<Type, PointerT>::Singleton(pointer ptr)
0245 {
0246 Initialize(ptr);
0247 }
0248
0249
0250
0251 template <typename Type, typename PointerT>
0252 Singleton<Type, PointerT>::~Singleton()
0253 {
0254 auto& del = GetDeleter();
0255 del(_master_instance());
0256 }
0257
0258
0259
0260 template <typename Type, typename PointerT>
0261 void
0262 Singleton<Type, PointerT>::Initialize()
0263 {
0264 if(!f_master_instance())
0265 {
0266 f_master_thread() = std::this_thread::get_id();
0267 f_master_instance() = new Type();
0268 }
0269 }
0270
0271
0272
0273 template <typename Type, typename PointerT>
0274 void
0275 Singleton<Type, PointerT>::Initialize(pointer ptr)
0276 {
0277 if(!f_master_instance())
0278 {
0279 f_master_thread() = std::this_thread::get_id();
0280 f_master_instance() = ptr;
0281 }
0282 }
0283
0284
0285
0286 template <typename Type, typename PointerT>
0287 void
0288 Singleton<Type, PointerT>::Destroy()
0289 {
0290 if(std::this_thread::get_id() == f_master_thread() && f_master_instance())
0291 {
0292 delete f_master_instance();
0293 f_master_instance() = nullptr;
0294 }
0295 else
0296 {
0297 remove(_local_instance().get());
0298 }
0299 }
0300
0301
0302
0303 template <typename Type, typename PointerT>
0304 typename Singleton<Type, PointerT>::pointer
0305 Singleton<Type, PointerT>::GetInstance()
0306 {
0307 if(std::this_thread::get_id() == f_master_thread())
0308 return GetMasterInstance();
0309 else if(!_local_instance().get())
0310 {
0311 _local_instance().reset(new Type());
0312 Insert(_local_instance().get());
0313 }
0314 return _local_instance().get();
0315 }
0316
0317
0318
0319 template <typename Type, typename PointerT>
0320 typename Singleton<Type, PointerT>::pointer
0321 Singleton<Type, PointerT>::GetMasterInstance()
0322 {
0323 if(!f_master_instance())
0324 {
0325 f_master_thread() = std::this_thread::get_id();
0326 f_master_instance() = new Type();
0327 }
0328 return f_master_instance();
0329 }
0330
0331
0332
0333 template <typename Type, typename PointerT>
0334 void
0335 Singleton<Type, PointerT>::Reset(pointer ptr)
0336 {
0337 if(IsMaster(ptr))
0338 {
0339 if(_master_instance().get())
0340 _master_instance().reset();
0341 else if(f_master_instance())
0342 {
0343 auto& del = GetDeleter();
0344 del(_master_instance());
0345 f_master_instance() = nullptr;
0346 }
0347 f_persistent_data().reset();
0348 }
0349 else
0350 {
0351 _local_instance().reset();
0352 }
0353 }
0354
0355
0356
0357 template <typename Type, typename PointerT>
0358 void
0359 Singleton<Type, PointerT>::Reset()
0360 {
0361 if(IsMasterThread())
0362 _master_instance().reset();
0363 _local_instance().reset();
0364 f_persistent_data().reset();
0365 }
0366
0367
0368
0369 template <typename Type, typename PointerT>
0370 bool
0371 Singleton<Type, PointerT>::IsMasterThread()
0372 {
0373 return std::this_thread::get_id() == f_master_thread();
0374 }
0375
0376
0377
0378 template <typename Type, typename PointerT>
0379 void
0380 Singleton<Type, PointerT>::Insert(pointer itr)
0381 {
0382 auto_lock_t l(f_mutex());
0383 f_children().insert(itr);
0384 }
0385
0386
0387
0388 template <typename Type, typename PointerT>
0389 void
0390 Singleton<Type, PointerT>::Remove(pointer itr)
0391 {
0392 auto_lock_t l(f_mutex());
0393 for(auto litr = f_children().begin(); litr != f_children().end(); ++litr)
0394 {
0395 if(*litr == itr)
0396 {
0397 f_children().erase(litr);
0398 break;
0399 }
0400 }
0401 }
0402
0403
0404
0405 }