summaryrefslogtreecommitdiff
path: root/indra/llcommon/llsingleton.h
diff options
context:
space:
mode:
authorbrad kittenbrink <brad@lindenlab.com>2009-08-05 14:58:30 -0700
committerbrad kittenbrink <brad@lindenlab.com>2009-08-05 14:58:30 -0700
commit860a82863966435bea680d8541f051e99a6c226c (patch)
tree6ef0bfa16e1ce8295f0b552daf7557a7a17a9af7 /indra/llcommon/llsingleton.h
parentdc62495da6e5c153c0df57fdbce6b0f40c0208f2 (diff)
Attemt at fixing "doubleton" problems across shared lib boundaries. Singletons now keep their SingletonInstaceData in a big global map in the llcommon module.
Diffstat (limited to 'indra/llcommon/llsingleton.h')
-rw-r--r--indra/llcommon/llsingleton.h33
1 files changed, 32 insertions, 1 deletions
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index dc1457e4f7..cd3963b260 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -33,7 +33,30 @@
#include "llerror.h" // *TODO: eliminate this
+#include <typeinfo>
#include <boost/noncopyable.hpp>
+#include <boost/any.hpp>
+
+/// @brief A global registry of all singletons to prevent duplicate allocations
+/// across shared library boundaries
+class LL_COMMON_API LLSingletonRegistry {
+ private:
+ typedef std::map<std::string, void *> TypeMap;
+ static TypeMap sSingletonMap;
+
+ public:
+ template<typename T> static void * & get()
+ {
+ std::string name(typeid(T).name());
+
+ if(0 == sSingletonMap.count(name))
+ {
+ sSingletonMap[name] = NULL;
+ }
+
+ return sSingletonMap[typeid(T).name()];
+ }
+};
// LLSingleton implements the getInstance() method part of the Singleton
// pattern. It can't make the derived class constructors protected, though, so
@@ -107,8 +130,16 @@ public:
static SingletonInstanceData& getData()
{
+ void * & registry = LLSingletonRegistry::get<DERIVED_TYPE>();
static SingletonInstanceData data;
- return data;
+
+ // *TODO - look into making this threadsafe
+ if(NULL == registry)
+ {
+ registry = &data;
+ }
+
+ return *static_cast<SingletonInstanceData *>(registry);
}
static DERIVED_TYPE* getInstance()