summaryrefslogtreecommitdiff
path: root/indra/llcommon
diff options
context:
space:
mode:
authorsimon <none@none>2013-05-01 14:44:09 -0700
committersimon <none@none>2013-05-01 14:44:09 -0700
commit348d4b66806cca07c91cab63f810d3d986e12377 (patch)
tree5fd54f9637da3cec54368e8c6cc9cf76f4bcad63 /indra/llcommon
parentcf37c677643b5b147e060e138dd9307ee36af677 (diff)
Manually pull in Richard's fixes for llcommon/llsingleton.h
Diffstat (limited to 'indra/llcommon')
-rw-r--r--indra/llcommon/llsingleton.h101
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