From 860a82863966435bea680d8541f051e99a6c226c Mon Sep 17 00:00:00 2001
From: brad kittenbrink <brad@lindenlab.com>
Date: Wed, 5 Aug 2009 14:58:30 -0700
Subject: Attemt at fixing "doubleton" problems across shared lib boundaries. 
 Singletons now keep their SingletonInstaceData in a big global map in the
 llcommon module.

---
 indra/llcommon/CMakeLists.txt  |  1 +
 indra/llcommon/llsingleton.cpp | 38 ++++++++++++++++++++++++++++++++++++++
 indra/llcommon/llsingleton.h   | 33 ++++++++++++++++++++++++++++++++-
 3 files changed, 71 insertions(+), 1 deletion(-)
 create mode 100644 indra/llcommon/llsingleton.cpp

diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 410cd0f6b2..7fe4491a8b 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -74,6 +74,7 @@ set(llcommon_SOURCE_FILES
     llsdserialize_xml.cpp
     llsdutil.cpp
     llsecondlifeurls.cpp
+    llsingleton.cpp
     llstat.cpp
     llstacktrace.cpp
     llstreamtools.cpp
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
new file mode 100644
index 0000000000..62988cdc64
--- /dev/null
+++ b/indra/llcommon/llsingleton.cpp
@@ -0,0 +1,38 @@
+/** 
+ * @file llsingleton.cpp
+ * @author Brad Kittenbrink
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009-2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llsingleton.h"
+
+std::map<std::string, void *> LLSingletonRegistry::sSingletonMap;
+
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()
-- 
cgit v1.2.3