From 553bd3246b763345bd9fae6a388dee161479c353 Mon Sep 17 00:00:00 2001
From: Gunnar Beutner <gunnar@beutner.name>
Date: Sat, 30 Nov 2013 17:47:53 +0100
Subject: [PATCH] Improve compatibility with -fvisibility=hidden.

Refs #5246
---
 lib/base/initialize.h       |  2 +-
 lib/base/registry.h         |  6 ------
 lib/base/scriptfunction.cpp |  7 +++++++
 lib/base/scriptfunction.h   |  6 +++++-
 lib/base/scriptvariable.cpp |  8 +++-----
 lib/base/scriptvariable.h   | 10 ++++++++++
 lib/base/threadpool.cpp     |  1 -
 lib/config/configcompiler.h | 23 ++++++++++++-----------
 lib/config/configtype.cpp   | 16 +++++++++++-----
 lib/config/configtype.h     |  7 +++++++
 lib/db_ido/dbtype.h         | 11 +++++++++--
 11 files changed, 65 insertions(+), 32 deletions(-)

diff --git a/lib/base/initialize.h b/lib/base/initialize.h
index f465176dc..9076c53af 100644
--- a/lib/base/initialize.h
+++ b/lib/base/initialize.h
@@ -36,7 +36,7 @@ inline bool InitializeOnceHelper(InitializeFunc func)
 
 #define INITIALIZE_ONCE(func) \
 	namespace { \
-		I2_EXPORT bool l_InitializeOnce(InitializeOnceHelper(func)); \
+		I2_EXPORT bool l_InitializeOnce(icinga::InitializeOnceHelper(func)); \
 	}
 
 }
diff --git a/lib/base/registry.h b/lib/base/registry.h
index 666fa9f59..3940f6a2e 100644
--- a/lib/base/registry.h
+++ b/lib/base/registry.h
@@ -21,7 +21,6 @@
 #define REGISTRY_H
 
 #include "base/i2-base.h"
-#include "base/singleton.h"
 #include "base/qstring.h"
 #include <map>
 #include <boost/thread/mutex.hpp>
@@ -42,11 +41,6 @@ class Registry
 public:
 	typedef std::map<String, T> ItemMap;
 
-	static Registry<U, T> *GetInstance(void)
-	{
-		return Singleton<Registry<U, T> >::GetInstance();
-	}
-
 	void RegisterIfNew(const String& name, const T& item)
 	{
 		boost::mutex::scoped_lock lock(m_Mutex);
diff --git a/lib/base/scriptfunction.cpp b/lib/base/scriptfunction.cpp
index 5a1e93619..a5488e986 100644
--- a/lib/base/scriptfunction.cpp
+++ b/lib/base/scriptfunction.cpp
@@ -19,6 +19,7 @@
 
 #include "base/scriptfunction.h"
 #include "base/registry.h"
+#include "base/singleton.h"
 
 using namespace icinga;
 
@@ -36,3 +37,9 @@ RegisterFunctionHelper::RegisterFunctionHelper(const String& name, const ScriptF
 	ScriptFunction::Ptr func = make_shared<ScriptFunction>(function);
 	ScriptFunctionRegistry::GetInstance()->Register(name, func);
 }
+
+ScriptFunctionRegistry *ScriptFunctionRegistry::GetInstance(void)
+{
+	return Singleton<ScriptFunctionRegistry>::GetInstance();
+}
+
diff --git a/lib/base/scriptfunction.h b/lib/base/scriptfunction.h
index e0299ad4d..1fa584747 100644
--- a/lib/base/scriptfunction.h
+++ b/lib/base/scriptfunction.h
@@ -22,6 +22,7 @@
 
 #include "base/i2-base.h"
 #include "base/registry.h"
+#include "base/singleton.h"
 #include "base/value.h"
 #include "base/scriptfunctionwrapper.h"
 #include <vector>
@@ -56,7 +57,10 @@ private:
  * @ingroup base
  */
 class I2_BASE_API ScriptFunctionRegistry : public Registry<ScriptFunctionRegistry, ScriptFunction::Ptr>
-{ };
+{
+public:
+	static ScriptFunctionRegistry *GetInstance(void);
+};
 
 /**
  * Helper class for registering ScriptFunction implementation classes.
diff --git a/lib/base/scriptvariable.cpp b/lib/base/scriptvariable.cpp
index 73d7ff228..5ae703451 100644
--- a/lib/base/scriptvariable.cpp
+++ b/lib/base/scriptvariable.cpp
@@ -22,11 +22,9 @@
 
 using namespace icinga;
 
-Registry<ScriptVariable, Value> ScriptVariable::m_Registry;
-
 Value ScriptVariable::Get(const String& name)
 {
-	Value value = m_Registry.GetItem(name);
+	Value value = ScriptVariableRegistry::GetInstance()->GetItem(name);
 	if (value.IsEmpty())
 		Log(LogWarning, "icinga", "Tried to access empty variable: " + name);
 
@@ -35,10 +33,10 @@ Value ScriptVariable::Get(const String& name)
 
 void ScriptVariable::Set(const String& name, const Value& value)
 {
-	m_Registry.Register(name, value);
+	ScriptVariableRegistry::GetInstance()->Register(name, value);
 }
 
 void ScriptVariable::Declare(const String& name, const Value& value)
 {
-	m_Registry.RegisterIfNew(name, value);
+	ScriptVariableRegistry::GetInstance()->RegisterIfNew(name, value);
 }
diff --git a/lib/base/scriptvariable.h b/lib/base/scriptvariable.h
index 7f44ce27d..b50dc47f6 100644
--- a/lib/base/scriptvariable.h
+++ b/lib/base/scriptvariable.h
@@ -22,6 +22,7 @@
 
 #include "base/i2-base.h"
 #include "base/registry.h"
+#include "base/singleton.h"
 #include "base/value.h"
 
 namespace icinga
@@ -43,6 +44,15 @@ private:
 	static Registry<ScriptVariable, Value> m_Registry;
 };
 
+class I2_BASE_API ScriptVariableRegistry : public Registry<ScriptVariableRegistry, Value>
+{
+public:
+	static inline ScriptVariableRegistry *GetInstance(void)
+	{
+		return Singleton<ScriptVariableRegistry>::GetInstance();
+	}
+};
+
 }
 
 #endif /* SCRIPTVARIABLE_H */
diff --git a/lib/base/threadpool.cpp b/lib/base/threadpool.cpp
index 257a67902..f15d07c24 100644
--- a/lib/base/threadpool.cpp
+++ b/lib/base/threadpool.cpp
@@ -22,7 +22,6 @@
 #include "base/convert.h"
 #include "base/debug.h"
 #include "base/utility.h"
-#include "base/scriptvariable.h"
 #include "base/application.h"
 #include "base/exception.h"
 #include <sstream>
diff --git a/lib/config/configcompiler.h b/lib/config/configcompiler.h
index c38fd4f96..fbb796ed8 100644
--- a/lib/config/configcompiler.h
+++ b/lib/config/configcompiler.h
@@ -23,6 +23,8 @@
 #include "config/i2-config.h"
 #include "config/debuginfo.h"
 #include "base/registry.h"
+#include "base/initialize.h"
+#include "base/singleton.h"
 #include <iostream>
 #include <boost/function.hpp>
 
@@ -72,24 +74,23 @@ private:
 };
 
 class I2_CONFIG_API ConfigFragmentRegistry : public Registry<ConfigFragmentRegistry, String>
-{ };
-
-/**
- * Helper class for registering config fragments.
- *
- * @ingroup base
- */
-class RegisterConfigFragmentHelper
 {
 public:
-	RegisterConfigFragmentHelper(const String& name, const String& fragment)
+	static inline ConfigFragmentRegistry *GetInstance(void)
 	{
-		ConfigFragmentRegistry::GetInstance()->Register(name, fragment);
+		return Singleton<ConfigFragmentRegistry>::GetInstance();
 	}
 };
 
 #define REGISTER_CONFIG_FRAGMENT(id, name, fragment) \
-	I2_EXPORT icinga::RegisterConfigFragmentHelper g_RegisterCF_ ## id(name, fragment)
+	namespace { \
+		void RegisterConfigFragment(void) \
+		{ \
+			icinga::ConfigFragmentRegistry::GetInstance()->Register(name, fragment); \
+		} \
+		\
+		INITIALIZE_ONCE(RegisterConfigFragment); \
+	}
 
 }
 
diff --git a/lib/config/configtype.cpp b/lib/config/configtype.cpp
index d9b1106f8..3174e9516 100644
--- a/lib/config/configtype.cpp
+++ b/lib/config/configtype.cpp
@@ -278,20 +278,26 @@ void ConfigType::ValidateArray(const Array::Ptr& array,
 
 void ConfigType::Register(void)
 {
-	Registry<ConfigType, ConfigType::Ptr>::GetInstance()->Register(GetName(), GetSelf());
+	ConfigTypeRegistry::GetInstance()->Register(GetName(), GetSelf());
 }
 
 ConfigType::Ptr ConfigType::GetByName(const String& name)
 {
-	return Registry<ConfigType, ConfigType::Ptr>::GetInstance()->GetItem(name);
+	return ConfigTypeRegistry::GetInstance()->GetItem(name);
 }
 
-Registry<ConfigType, ConfigType::Ptr>::ItemMap ConfigType::GetTypes(void)
+ConfigTypeRegistry::ItemMap ConfigType::GetTypes(void)
 {
-	return Registry<ConfigType, ConfigType::Ptr>::GetInstance()->GetItems();
+	return ConfigTypeRegistry::GetInstance()->GetItems();
 }
 
 void ConfigType::DiscardTypes(void)
 {
-	Registry<ConfigType, ConfigType::Ptr>::GetInstance()->Clear();
+	ConfigTypeRegistry::GetInstance()->Clear();
 }
+
+ConfigTypeRegistry *ConfigTypeRegistry::GetInstance(void)
+{
+	return Singleton<ConfigTypeRegistry>::GetInstance();
+}
+
diff --git a/lib/config/configtype.h b/lib/config/configtype.h
index feedb0639..ff02f9af5 100644
--- a/lib/config/configtype.h
+++ b/lib/config/configtype.h
@@ -26,6 +26,7 @@
 #include "config/configitem.h"
 #include "base/array.h"
 #include "base/registry.h"
+#include "base/singleton.h"
 
 namespace icinga
 {
@@ -74,6 +75,12 @@ private:
 	static void AddParentRules(std::vector<TypeRuleList::Ptr>& ruleLists, const ConfigType::Ptr& item);
 };
 
+class I2_CONFIG_API ConfigTypeRegistry : public Registry<ConfigTypeRegistry, ConfigType::Ptr>
+{
+public:
+	static ConfigTypeRegistry *GetInstance(void);
+};
+
 }
 
 #endif /* CONFIGTYPE_H */
diff --git a/lib/db_ido/dbtype.h b/lib/db_ido/dbtype.h
index 65e52b8ed..66fc3a843 100644
--- a/lib/db_ido/dbtype.h
+++ b/lib/db_ido/dbtype.h
@@ -23,6 +23,7 @@
 #include "db_ido/i2-db_ido.h"
 #include "base/object.h"
 #include "base/registry.h"
+#include "base/singleton.h"
 
 namespace icinga
 {
@@ -75,8 +76,14 @@ private:
  *
  * @ingroup ido
  */
-class DbTypeRegistry : public Registry<DbTypeRegistry, DbType::Ptr>
-{ };
+class I2_DB_IDO_API DbTypeRegistry : public Registry<DbTypeRegistry, DbType::Ptr>
+{
+public:
+	static inline DbTypeRegistry *GetInstance(void)
+	{
+		return Singleton<DbTypeRegistry>::GetInstance();
+	}
+};
 
 /**
  * Helper class for registering DynamicObject implementation classes.