From d6d7bbc9c32d5c060e48a3cfae006871f756cfaf Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Wed, 8 Oct 2014 09:36:50 +0200 Subject: added flags to module loader, CLOSE_DEFERRED is deferring dlclose with a atexit function, so that the tolua test runs now --- include/module/ModuleLoader.hpp | 70 +++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/include/module/ModuleLoader.hpp b/include/module/ModuleLoader.hpp index 2ae8421..9340166 100755 --- a/include/module/ModuleLoader.hpp +++ b/include/module/ModuleLoader.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #ifndef _WIN32 #include @@ -21,13 +22,15 @@ #include "TypeList.hpp" #include "TypeInfo.hpp" -template< typename Interface, typename CtorParams = NullType > -struct Module { #ifndef _WIN32 - void *handle; +typedef void * ModuleHandle; #else - HMODULE handle; +typedef HMODULE ModuleHandle; #endif + +template< typename Interface, typename CtorParams = NullType > +struct Module { + ModuleHandle handle; void *user_data; ModuleRegistry< Interface, CtorParams > *registry; @@ -43,6 +46,26 @@ struct Module { } }; +static size_t nofDeferredModules = 0; +static size_t sizeofDeferredModules = 0; +static ModuleHandle* deferredModules = 0; + +const int CLOSE_ON_DTOR = 0; +const int CLOSE_DEFERRED = 1; + +const int DEFAULT_FLAGS = CLOSE_ON_DTOR; + +static void deferredClose( void ) +{ + for( size_t i = 0; i <= nofDeferredModules - 1; i++ ) { +#ifndef _WIN32 + dlclose( deferredModules[i] ); +#else + (void)FreeLibrary( deferredModules[i] ); +#endif + } +} + template< typename Interface, typename CtorParams = NullType > class BaseModuleLoader { @@ -53,10 +76,12 @@ class BaseModuleLoader { protected: mapType m_modules; + int m_flags; public: - BaseModuleLoader( const std::vector files, void *user_data = 0 ) + BaseModuleLoader( const std::vector files, int flags = DEFAULT_FLAGS, void *user_data = 0 ) + : m_flags( flags ) { for( std::vector::const_iterator it = files.begin( ); it != files.end( ); it++ ) { @@ -114,11 +139,22 @@ class BaseModuleLoader { } } if( (*it).second.handle ) { + if( m_flags & CLOSE_DEFERRED ) { + if( nofDeferredModules == 0 ) { + atexit( &deferredClose ); + } + if( nofDeferredModules + 1 >= sizeofDeferredModules ) { + sizeofDeferredModules = ( sizeofDeferredModules + 1 ) * 2; + deferredModules = (ModuleHandle *)realloc( deferredModules, sizeofDeferredModules * sizeof( ModuleHandle * ) ); + deferredModules[nofDeferredModules++] = (*it).second.handle; + } + } else { #ifndef _WIN32 - dlclose( (*it).second.handle ); + dlclose( (*it).second.handle ); #else - (void)FreeLibrary( (*it).second.handle ); + (void)FreeLibrary( (*it).second.handle ); #endif + } } } @@ -145,8 +181,8 @@ class ModuleLoader< Interface, NullType > : public BaseModuleLoader< Interface, { public: - ModuleLoader< Interface >( const std::vector files, void *user_data = 0 ) - : BaseModuleLoader< Interface >( files, user_data ) { } + ModuleLoader< Interface >( const std::vector files, int flags = DEFAULT_FLAGS, void *user_data = 0 ) + : BaseModuleLoader< Interface >( files, flags, user_data ) { } Interface *create( std::string subclass ) { @@ -174,8 +210,8 @@ class ModuleLoader< Interface, TYPELIST_1( T1 ) > : public BaseModuleLoader< Int { public: - ModuleLoader< Interface, TYPELIST_1( T1 ) >( const std::vector files, void *user_data = 0 ) - : BaseModuleLoader< Interface, TYPELIST_1( T1 ) >( files, user_data ) { } + ModuleLoader< Interface, TYPELIST_1( T1 ) >( const std::vector files, int flags = DEFAULT_FLAGS, void *user_data = 0 ) + : BaseModuleLoader< Interface, TYPELIST_1( T1 ) >( files, flags, user_data ) { } Interface *create( std::string subclass, T1 t1 ) { @@ -203,8 +239,8 @@ class ModuleLoader< Interface, TYPELIST_2( T1, T2 ) > : public BaseModuleLoader< { public: - ModuleLoader< Interface, TYPELIST_2( T1, T2 ) >( const std::vector files, void *user_data = 0 ) - : BaseModuleLoader< Interface, TYPELIST_2( T1, T2 ) >( files, user_data ) { } + ModuleLoader< Interface, TYPELIST_2( T1, T2 ) >( const std::vector files, int flags = DEFAULT_FLAGS, void *user_data = 0 ) + : BaseModuleLoader< Interface, TYPELIST_2( T1, T2 ) >( files, flags, user_data ) { } Interface *create( std::string subclass, T1 t1, T2 t2 ) { @@ -232,8 +268,8 @@ class ModuleLoader< Interface, TYPELIST_3( T1, T2, T3 ) > : public BaseModuleLoa { public: - ModuleLoader< Interface, TYPELIST_3( T1, T2, T3 ) >( const std::vector files, void *user_data = 0 ) - : BaseModuleLoader< Interface, TYPELIST_3( T1, T2, T3 ) >( files, user_data ) { } + ModuleLoader< Interface, TYPELIST_3( T1, T2, T3 ) >( const std::vector files, int flags = DEFAULT_FLAGS, void *user_data = 0 ) + : BaseModuleLoader< Interface, TYPELIST_3( T1, T2, T3 ) >( files, flags, user_data ) { } Interface *create( std::string subclass, T1 t1, T2 t2, T3 t3 ) { @@ -261,8 +297,8 @@ class ModuleLoader< Interface, TYPELIST_4( T1, T2, T3, T4 ) > : public BaseModul { public: - ModuleLoader< Interface, TYPELIST_4( T1, T2, T3, T4 ) >( const std::vector files, void *user_data = 0 ) - : BaseModuleLoader< Interface, TYPELIST_4( T1, T2, T3, T4 ) >( files, user_data ) { } + ModuleLoader< Interface, TYPELIST_4( T1, T2, T3, T4 ) >( const std::vector files, int flags = DEFAULT_FLAGS, void *user_data = 0 ) + : BaseModuleLoader< Interface, TYPELIST_4( T1, T2, T3, T4 ) >( files, flags, user_data ) { } Interface *create( std::string subclass, T1 t1, T2 t2, T3 t3, T4 t4 ) { -- cgit v1.2.3-54-g00ecf