Re #374 (Move module system to a modern C++-styled implementation) Made GfModule::unload a static function for symmetry and fix of a crash

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@3460 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: d6d0ea2ee387f401dc5ac97c452d92fdc815cb8f
Former-commit-id: cf6f5d1028a59f6c043761da97fadcc5a5d6beba
This commit is contained in:
pouillot 2011-03-28 21:30:30 +00:00
parent 1a8dc7dfcb
commit fd72434200
2 changed files with 68 additions and 32 deletions

View file

@ -137,66 +137,88 @@ GfModule* GfModule::load(const std::string& strShLibName)
return _mapModulesByLibName[strShLibName];
}
bool GfModule::unload()
bool GfModule::unload(GfModule*& pModule)
{
if (_mapModulesByLibName.find(_strShLibName) == _mapModulesByLibName.end())
{
GfLogError("Can't unload not yet loaded module %s\n", _strShLibName.c_str());
return false;
}
// Try and get the module closing function.
tModCloseFunc modCloseFunc = (tModCloseFunc)dlsym(_hShLibHandle, pszCloseModuleFuncName);
std::string strShLibName = pModule->getSharedLibName();
void* hShLibHandle = pModule->getSharedLibHandle();
tModCloseFunc modCloseFunc = (tModCloseFunc)dlsym(hShLibHandle, pszCloseModuleFuncName);
if (!modCloseFunc)
{
GfLogWarning("Library %s doesn't export any '%s' function' ; not called\n",
_strShLibName.c_str(), pszCloseModuleFuncName);
strShLibName.c_str(), pszCloseModuleFuncName);
}
// Call the module closing function (must delete the module instance).
if (modCloseFunc())
{
GfLogWarning("Library %s '%s' function call failed ; going on\n",
_strShLibName.c_str(), pszCloseModuleFuncName);
strShLibName.c_str(), pszCloseModuleFuncName);
}
// Unregister the module.
_mapModulesByLibName.erase(_strShLibName);
// Make it clear that the passed pointer is no more usable (it was deleted).
pModule = 0;
// Try and close the shared library.
if (dlclose(_hShLibHandle))
if (dlclose(hShLibHandle))
{
GfLogWarning("Failed to unload library %s (%s) ; \n",
_strShLibName.c_str(), lastDLErrorString().c_str());
strShLibName.c_str(), lastDLErrorString().c_str());
return false;
}
GfLogTrace("Module %s unloaded\n", _strShLibName.c_str());
GfLogTrace("Module %s unloaded\n", strShLibName.c_str());
return true;
}
bool GfModule::register_(GfModule* pModule)
bool GfModule::register_(GfModule* pModule) // Can't use 'register' as it is a C++ keyword.
{
bool status = false;
bool bStatus = false;
if (pModule)
{
if (_mapModulesByLibName.find(pModule->getSharedLibName()) != _mapModulesByLibName.end())
{
GfLogError("Can't register another module in %s\n", pModule->getSharedLibName().c_str());
GfLogError("Can only register 1 module from %s\n", pModule->getSharedLibName().c_str());
}
else
{
_mapModulesByLibName[pModule->getSharedLibName()] = pModule;
status = true;
bStatus = true;
}
}
return status;
return bStatus;
}
bool GfModule::unregister(GfModule* pModule)
{
bool bStatus = false;
if (pModule)
{
if (_mapModulesByLibName.find(pModule->getSharedLibName()) == _mapModulesByLibName.end())
{
GfLogError("Can't unregister module in %s (not yet registered)\n",
pModule->getSharedLibName().c_str());
}
else
{
_mapModulesByLibName.erase(pModule->getSharedLibName());
bStatus = true;
}
}
return bStatus;
}
const std::string& GfModule::getSharedLibName() const
{
return _strShLibName;
}
void* GfModule::getSharedLibHandle() const
{
return _hShLibHandle;
}

View file

@ -24,10 +24,10 @@
#ifndef __TGF__HPP__
#define __TGF__HPP__
#ifdef _MSC_VER
// Disable useless MSVC warnings
# pragma warning (disable:4251) // class XXX needs a DLL interface ...
#endif
#ifdef _MSC_VER
// Disable useless MSVC warnings
# pragma warning (disable:4251) // class XXX needs a DLL interface ...
#endif
#include <string>
#include <map>
@ -36,11 +36,17 @@
//****************************************
// New dynamicaly loadable modules system
// * 1 module per shared library
// * the shared library exports 2 extern "C" functions :
// - bool initializeModule(); // TODO: find a different name (legacy welcome modules)
// - bool terminateModule(); // Idem
// New dynamically loadable modules system
// - 1 and only 1 module per shared library,
// - a module is a GfModule-derived class instance (and even a singleton),
// - the shared library exports 2 extern 'C' functions :
// - int openGfModule(const char* pszShLibName, void* hShLibHandle) :
// it must instanciate the module class (new), register the module instance (register_),
// initialize / allocate any needed internal resource and finally return 0
// if everything is OK, non-0 otherwise;
// - int closeGfModule() :
// it must release any allocated resource, unregister the module instance (unregister),
// and finally return 0, non-0 otherwise.
class TGF_API GfModule
{
@ -49,8 +55,8 @@ class TGF_API GfModule
//! Load a module from the given module library file.
static GfModule* load(const std::string& strShLibName);
//! Unload a module and the associated library (supposed to contain no other module).
virtual bool unload();
//! Delete a module and unload the associated library (supposed to contain no other module).
static bool unload(GfModule*& pModule);
//! Get the module as a pointer to the given interface (aka "facet").
template <class Interface>
@ -73,6 +79,14 @@ class TGF_API GfModule
//! Get the asssociated shared library path-name.
const std::string& getSharedLibName() const;
//! Get the asssociated shared library handle.
void* getSharedLibHandle() const;
protected:
//! Unregister a module instance.
static bool unregister(GfModule* pModule);
protected:
//! The table of loaded modules and their associated shared library (key = file name).