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:
parent
1a8dc7dfcb
commit
fd72434200
2 changed files with 68 additions and 32 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
Loading…
Reference in a new issue