diff options
| author | Willem Jan Palenstijn <wjp@usecode.org> | 2016-05-17 17:19:31 +0200 | 
|---|---|---|
| committer | Willem Jan Palenstijn <wjp@usecode.org> | 2016-05-17 17:19:31 +0200 | 
| commit | 844a9f71fba18c76d6b3566b78908877a0a1a9c8 (patch) | |
| tree | adb88053a6e68003ff57dd2dfc8dc6d07b728aa5 | |
| parent | d60df8bbd0e17016036c279720d6e3464a4d295c (diff) | |
| parent | f9b68bafd90941d9faf53e5e2771361e3ab4336a (diff) | |
| download | astra-844a9f71fba18c76d6b3566b78908877a0a1a9c8.tar.gz astra-844a9f71fba18c76d6b3566b78908877a0a1a9c8.tar.bz2 astra-844a9f71fba18c76d6b3566b78908877a0a1a9c8.tar.xz astra-844a9f71fba18c76d6b3566b78908877a0a1a9c8.zip | |
Merge pull request #55 from wjp/singleton_construction
Avoid defining singleton construction in header file
| -rw-r--r-- | include/astra/Singleton.h | 22 | 
1 files changed, 18 insertions, 4 deletions
| diff --git a/include/astra/Singleton.h b/include/astra/Singleton.h index a256187..784c521 100644 --- a/include/astra/Singleton.h +++ b/include/astra/Singleton.h @@ -57,15 +57,17 @@ class Singleton {  			m_singleton = 0;  		} +		static void construct(); +  		// get singleton  		static T& getSingleton() {  			if (!m_singleton) -				m_singleton = new T(); +				construct();  			return *m_singleton;  		}  		static T* getSingletonPtr() {  			if (!m_singleton) -				m_singleton = new T(); +				construct();  			return m_singleton;  		} @@ -76,11 +78,23 @@ class Singleton {  }; -#define DEFINE_SINGLETON(T) template<> T* Singleton<T >::m_singleton = 0 +// We specifically avoid defining construct() in the header. +// That way, the call to new is always executed by code inside libastra. +// This avoids the situation where a singleton gets created by a copy +// of the constructor linked into an object file outside of libastra, such +// as a .mex file, which would then also cause the vtable to be outside of +// libastra. This situation would cause issues when .mex files are unloaded. + +#define DEFINE_SINGLETON(T) \ +template<> void Singleton<T >::construct() { assert(!m_singleton); m_singleton = new T(); } \ +template<> T* Singleton<T >::m_singleton = 0 +  // This is a hack to support statements like  // DEFINE_SINGLETON2(CTemplatedClass<C1, C2>); -#define DEFINE_SINGLETON2(A,B) template<> A,B* Singleton<A,B >::m_singleton = 0 +#define DEFINE_SINGLETON2(A,B) \ +template<> void Singleton<A,B >::construct() { assert(!m_singleton); m_singleton = new A,B(); } \ +template<> A,B* Singleton<A,B >::m_singleton = 0  } // end namespace | 
