summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Linden <none@none>2013-04-27 07:42:32 -0700
committerRichard Linden <none@none>2013-04-27 07:42:32 -0700
commit215612bde86969e49ff9577d1d64390696280b3e (patch)
treed137bb34a7493eb8820fdd127c7d1f79015051af
parenta4e53da0b0d8f227865303a785d3d65848cd4ade (diff)
SH-4080 WIP interesting: random crash on Mac
more singleton cleanup to eliminate crashes on startup/exit
-rw-r--r--indra/llcommon/llsingleton.h95
1 files changed, 45 insertions, 50 deletions
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 829c7e4192..7558bf4fae 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,30 +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();
}
- void construct()
+ static void construct()
{
- sReentrantConstructorGuard = true;
- mSingletonInstance = new DERIVED_TYPE();
- mInitState = INITIALIZING;
- sReentrantConstructorGuard = false;
+ sData.mInitState = CONSTRUCTING;
+ sData.mInstance = new DERIVED_TYPE();
+ sData.mInitState = INITIALIZING;
}
- ~SingletonInstanceData()
+ ~SingletonLifetimeManager()
{
- if (mInitState != DELETED)
+ if (sData.mInitState != DELETED)
{
deleteSingleton();
}
@@ -101,9 +95,8 @@ private:
public:
virtual ~LLSingleton()
{
- SingletonInstanceData& data = getSingletonData();
- data.mSingletonInstance = NULL;
- data.mInitState = DELETED;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
/**
@@ -128,41 +121,45 @@ public:
*/
static void deleteSingleton()
{
- delete getSingletonData().mSingletonInstance;
- getSingletonData().mSingletonInstance = NULL;
- getSingletonData().mInitState = DELETED;
+ delete sData.mInstance;
+ sData.mInstance = NULL;
+ sData.mInitState = DELETED;
}
static DERIVED_TYPE* getInstance()
{
- SingletonInstanceData& data = getSingletonData();
+ static SingletonLifetimeManager sLifeTimeMgr;
- if (data.mInitState == CONSTRUCTING)
+ switch (sData.mInitState)
{
+ case UNINITIALIZED:
+ // should never be uninitialized at this point
+ llassert(false);
+ break;
+ 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.construct();
- }
-
- if (data.mInitState == INITIALIZING)
- {
+ break;
+ 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;
+ break;
+ case INITIALIZED:
+ return sData.mInstance;
+ case DELETED:
+ llwarns << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << llendl;
+ SingletonLifetimeManager::construct();
+ return sData.mInstance;
}
-
- return data.mSingletonInstance;
+
+ return NULL;
}
static DERIVED_TYPE* getIfExists()
{
- SingletonInstanceData& data = getSingletonData();
- return data.mSingletonInstance;
+ return sData.mInstance;
}
// Reference version of getInstance()
@@ -176,31 +173,29 @@ public:
// Use this to avoid accessing singletons before the can safely be constructed
static bool instanceExists()
{
- return !sReentrantConstructorGuard && getSingletonData().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 getSingletonData().mInitState == DELETED;
+ return sData.mInitState == DELETED;
}
private:
- static SingletonInstanceData& getSingletonData()
- {
- // this is static to cache the lookup results
- static SingletonInstanceData sData;
- return sData;
- }
-
virtual void initSingleton() {}
- static bool sReentrantConstructorGuard;
+ struct SingletonData
+ {
+ EInitState mInitState;
+ DERIVED_TYPE* mInstance;
+ };
+ static SingletonData sData;
};
template<typename T>
-bool LLSingleton<T>::sReentrantConstructorGuard = false;
+typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
#endif