Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 3.3 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00008 #ifndef vsingleton_h 00009 #define vsingleton_h 00010 00011 #include "vshutdownregistry.h" 00012 #include "vmutexlocker.h" 00013 #include "vexception.h" 00014 00085 template <class T> 00086 class VSingleton : public IVShutdownHandler { 00087 public: 00088 00090 enum HolderDeletionPolicy { kDeleteHolderAtShutdown, kDontDeleteHolderAtShutdown }; 00092 enum ThreadSafetyPolicy { kThreadSafeAccess, kSimpleAccess }; 00094 enum ShutdownPolicy { kRegisterForShutdown, kDontRegisterForShutdown }; 00096 enum ResurrectionPolicy { kDontAllowResurrection, kAllowResurrection }; 00097 00105 VSingleton(HolderDeletionPolicy holderDeletionPolicy, 00106 ThreadSafetyPolicy threadSafetyPolicy, 00107 ShutdownPolicy shutdownPolicy, 00108 ResurrectionPolicy resurrectionPolicy = kDontAllowResurrection) 00109 : IVShutdownHandler(holderDeletionPolicy == kDeleteHolderAtShutdown) 00110 , mThreadSafe(threadSafetyPolicy == kThreadSafeAccess) 00111 , mWantShutdown(shutdownPolicy == kRegisterForShutdown) 00112 , mAllowResurrection(resurrectionPolicy == kAllowResurrection) 00113 { 00114 } 00115 00116 ~VSingleton() {} 00117 00124 T* instance() { 00125 VMutexLocker locker(&gMutex, "VSingleton::instance()", mThreadSafe); 00126 00127 if (gInstance == NULL) { 00128 if (gInstanceDeleted && !mAllowResurrection) { 00129 throw VStackTraceException("VSingleton called with invalid attempt to get instance of deleted singleton."); 00130 } 00131 00132 gInstance = new T(); 00133 00134 if (mWantShutdown) { 00135 VShutdownRegistry::instance()->registerHandler(this); 00136 } 00137 } 00138 00139 return gInstance; 00140 } 00141 00145 void deleteInstance() { 00146 VMutexLocker locker(&gMutex, "VSingleton::deleteInstance()", mThreadSafe); 00147 delete gInstance; 00148 gInstance = NULL; 00149 gInstanceDeleted = true; 00150 } 00151 00152 protected: 00153 00158 virtual void _shutdown() { 00159 this->deleteInstance(); 00160 } 00161 00162 private: 00163 00164 static VMutex gMutex; 00165 static T* gInstance; 00166 static bool gInstanceDeleted; 00167 00168 bool mThreadSafe; 00169 bool mWantShutdown; 00170 bool mAllowResurrection; 00171 00172 }; 00173 00174 template <class T> VMutex VSingleton<T>::gMutex("VSingleton::gMutex"); 00175 template <class T> T* VSingleton<T>::gInstance = NULL; 00176 template <class T> bool VSingleton<T>::gInstanceDeleted = false; 00177 00178 #endif /* vsingleton_h */