diff options
author | simon <none@none> | 2013-05-01 14:44:09 -0700 |
---|---|---|
committer | simon <none@none> | 2013-05-01 14:44:09 -0700 |
commit | 348d4b66806cca07c91cab63f810d3d986e12377 (patch) | |
tree | 5fd54f9637da3cec54368e8c6cc9cf76f4bcad63 /indra/llcommon | |
parent | cf37c677643b5b147e060e138dd9307ee36af677 (diff) |
Manually pull in Richard's fixes for llcommon/llsingleton.h
Diffstat (limited to 'indra/llcommon')
-rw-r--r-- | indra/llcommon/llsingleton.h | 101 |
1 files changed, 58 insertions, 43 deletions
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h index 550e3c0d20..40002313f1 100644 --- a/indra/llcommon/llsingleton.h +++ b/indra/llcommon/llsingleton.h @@ -61,6 +61,7 @@ class LLSingleton : private boost::noncopyable private: typedef enum e_init_state { + UNINITIALIZED, CONSTRUCTING, INITIALIZING, INITIALIZED, @@ -68,23 +69,23 @@ private: } EInitState; // stores pointer to singleton instance - // and tracks initialization state of singleton - struct SingletonInstanceData + struct SingletonLifetimeManager { - EInitState mInitState; - DERIVED_TYPE* mSingletonInstance; - - SingletonInstanceData() - : mSingletonInstance(NULL), - mInitState(CONSTRUCTING) + SingletonLifetimeManager() + { + construct(); + } + + static void construct() { - mSingletonInstance = new DERIVED_TYPE(); - mInitState = INITIALIZING; + sData.mInitState = CONSTRUCTING; + sData.mInstance = new DERIVED_TYPE(); + sData.mInitState = INITIALIZING; } - ~SingletonInstanceData() + ~SingletonLifetimeManager() { - if (mInitState != DELETED) + if (sData.mInitState != DELETED) { deleteSingleton(); } @@ -94,9 +95,8 @@ private: public: virtual ~LLSingleton() { - SingletonInstanceData& data = getData(); - data.mSingletonInstance = NULL; - data.mInitState = DELETED; + sData.mInstance = NULL; + sData.mInitState = DELETED; } /** @@ -121,42 +121,46 @@ public: */ static void deleteSingleton() { - delete getData().mSingletonInstance; - getData().mSingletonInstance = NULL; - getData().mInitState = DELETED; + delete sData.mInstance; + sData.mInstance = NULL; + sData.mInitState = DELETED; } - static SingletonInstanceData& getData() - { - // this is static to cache the lookup results - static SingletonInstanceData sData; - return sData; - } static DERIVED_TYPE* getInstance() { - SingletonInstanceData& data = getData(); + static SingletonLifetimeManager sLifeTimeMgr; - if (data.mInitState == CONSTRUCTING) + switch (sData.mInitState) { + case UNINITIALIZED: + // should never be uninitialized at this point + llassert(false); + return NULL; + case CONSTRUCTING: llerrs << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << llendl; - } - - if (data.mInitState == DELETED) - { - llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl; - data.mSingletonInstance = new DERIVED_TYPE(); - data.mInitState = INITIALIZING; - } // Fall into INITIALIZING case below - - if (data.mInitState == INITIALIZING) - { + return NULL; + case INITIALIZING: // go ahead and flag ourselves as initialized so we can be reentrant during initialization - data.mInitState = INITIALIZED; - data.mSingletonInstance->initSingleton(); + sData.mInitState = INITIALIZED; + sData.mInstance->initSingleton(); + return sData.mInstance; + case INITIALIZED: + return sData.mInstance; + case DELETED: + llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl; + SingletonLifetimeManager::construct(); + sData.mInitState = INITIALIZED; + sData.mInstance->initSingleton(); + return sData.mInstance; } - - return data.mSingletonInstance; + + return NULL; + } + + static DERIVED_TYPE* getIfExists() + { + return sData.mInstance; } // Reference version of getInstance() @@ -170,18 +174,29 @@ public: // Use this to avoid accessing singletons before the can safely be constructed static bool instanceExists() { - return getData().mInitState == INITIALIZED; + return sData.mInitState == INITIALIZED; } // Has this singleton already been deleted? // Use this to avoid accessing singletons from a static object's destructor static bool destroyed() { - return getData().mInitState == DELETED; + return sData.mInitState == DELETED; } private: + virtual void initSingleton() {} + + struct SingletonData + { + EInitState mInitState; + DERIVED_TYPE* mInstance; + }; + static SingletonData sData; }; +template<typename T> +typename LLSingleton<T>::SingletonData LLSingleton<T>::sData; + #endif |