Skip to content
Snippets Groups Projects
Commit 58dd483a authored by Rye Mutt's avatar Rye Mutt :bread:
Browse files

Fast thread unsafe access to LLSingleton

parent 5e0bc223
No related branches found
No related tags found
No related merge requests found
...@@ -301,6 +301,10 @@ class LLSingleton : public LLSingletonBase ...@@ -301,6 +301,10 @@ class LLSingleton : public LLSingletonBase
}; };
typedef llthread::LockStaticLL<SingletonData> LockStatic; typedef llthread::LockStaticLL<SingletonData> LockStatic;
protected:
inline static DERIVED_TYPE* sUnsafeInstance = nullptr;
private:
// Allow LLParamSingleton subclass -- but NOT DERIVED_TYPE itself -- to // Allow LLParamSingleton subclass -- but NOT DERIVED_TYPE itself -- to
// access our private members. // access our private members.
friend class LLParamSingleton<DERIVED_TYPE>; friend class LLParamSingleton<DERIVED_TYPE>;
...@@ -348,6 +352,9 @@ class LLSingleton : public LLSingletonBase ...@@ -348,6 +352,9 @@ class LLSingleton : public LLSingletonBase
lk->mInstance->initSingleton(); lk->mInstance->initSingleton();
lk->mInitState = INITIALIZED; lk->mInitState = INITIALIZED;
// Cache for fast unsafe access
sUnsafeInstance = lk->mInstance;
// pop this off stack of initializing singletons // pop this off stack of initializing singletons
pop_initializing(lk->mInstance); pop_initializing(lk->mInstance);
} }
...@@ -416,6 +423,8 @@ class LLSingleton : public LLSingletonBase ...@@ -416,6 +423,8 @@ class LLSingleton : public LLSingletonBase
// deleteSingleton() to defend against manual deletion. When we moved // deleteSingleton() to defend against manual deletion. When we moved
// cleanup to deleteSingleton(), we hit crashes due to dangling // cleanup to deleteSingleton(), we hit crashes due to dangling
// pointers in the MasterList. // pointers in the MasterList.
sUnsafeInstance = nullptr;
LockStatic lk; LockStatic lk;
lk->mInstance = nullptr; lk->mInstance = nullptr;
lk->mInitState = DELETED; lk->mInitState = DELETED;
...@@ -577,6 +586,17 @@ class LLSingleton : public LLSingletonBase ...@@ -577,6 +586,17 @@ class LLSingleton : public LLSingletonBase
return instance; return instance;
} }
// Thread unsafe access
inline static DERIVED_TYPE* getInstanceFast()
{
if (!sUnsafeInstance)
{
// Dummy call to force populate
getInstance();
}
return sUnsafeInstance;
}
// Reference version of getInstance() // Reference version of getInstance()
// Preferred over getInstance() as it disallows checking for nullptr // Preferred over getInstance() as it disallows checking for nullptr
static DERIVED_TYPE& instance() static DERIVED_TYPE& instance()
...@@ -584,6 +604,12 @@ class LLSingleton : public LLSingletonBase ...@@ -584,6 +604,12 @@ class LLSingleton : public LLSingletonBase
return *getInstance(); return *getInstance();
} }
// Thread unsafe access
inline static DERIVED_TYPE& instanceFast()
{
return *getInstanceFast();
}
// Has this singleton been created yet? // Has this singleton been created yet?
// Use this to avoid accessing singletons before they can safely be constructed. // Use this to avoid accessing singletons before they can safely be constructed.
static bool instanceExists() static bool instanceExists()
...@@ -737,6 +763,16 @@ class LLParamSingleton : public LLSingleton<DERIVED_TYPE> ...@@ -737,6 +763,16 @@ class LLParamSingleton : public LLSingleton<DERIVED_TYPE>
return nullptr; return nullptr;
} }
static DERIVED_TYPE* getInstanceFast()
{
if (!super::sUnsafeInstance)
{
// Dummy call to force populate
getInstance();
}
return super::sUnsafeInstance;
}
// instance() is replicated here so it calls // instance() is replicated here so it calls
// LLParamSingleton::getInstance() rather than LLSingleton::getInstance() // LLParamSingleton::getInstance() rather than LLSingleton::getInstance()
// -- avoid making getInstance() virtual // -- avoid making getInstance() virtual
...@@ -744,6 +780,11 @@ class LLParamSingleton : public LLSingleton<DERIVED_TYPE> ...@@ -744,6 +780,11 @@ class LLParamSingleton : public LLSingleton<DERIVED_TYPE>
{ {
return *getInstance(); return *getInstance();
} }
static DERIVED_TYPE& instanceFast()
{
return *getInstanceFast();
}
}; };
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment