From fd68c0f047bbd40d02cad5a84584cc74979c993a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 1 Jul 2009 20:45:25 +0200 Subject: ModuleManager: Benutze libdl anstatt ltdl --- src/Common/CMakeLists.txt | 3 +- src/Common/ModuleManager.cpp | 79 ++++++++++++++++++++++++-------------------- src/Common/ModuleManager.h | 13 ++++---- 3 files changed, 51 insertions(+), 44 deletions(-) (limited to 'src/Common') diff --git a/src/Common/CMakeLists.txt b/src/Common/CMakeLists.txt index 74c5029..6076561 100644 --- a/src/Common/CMakeLists.txt +++ b/src/Common/CMakeLists.txt @@ -4,7 +4,6 @@ add_subdirectory(Requests) include_directories(${INCLUDES}) -link_directories(${LTDL_LIBRARY_DIR}) add_library(Common Application.cpp Application.h @@ -27,4 +26,4 @@ add_library(Common UserManager.cpp UserManager.h XmlPacket.cpp XmlPacket.h ) -target_link_libraries(Common Backends RequestHandlers Requests Net ${LIBXML2_LIBRARIES} ${LTDL_LIBRARIES}) +target_link_libraries(Common Backends RequestHandlers Requests Net ${LIBXML2_LIBRARIES} ${DL_LIBRARY}) diff --git a/src/Common/ModuleManager.cpp b/src/Common/ModuleManager.cpp index 25b0ee9..74c424d 100644 --- a/src/Common/ModuleManager.cpp +++ b/src/Common/ModuleManager.cpp @@ -26,37 +26,29 @@ #include #include -//extern const lt_dlsymlist lt_preloaded_symbols[]; +#include namespace Mad { namespace Common { -/*int ModuleManager::preopenCallback(lt_dlhandle handle) { - moduleManager.modules.insert(std::make_pair(lt_dlgetinfo(handle)->name, std::make_pair(handle, false))); - - return 0; -}*/ - ModuleManager::ModuleManager(Application *application0) : application(application0) { - lt_dlinit(); - - //lt_dlpreload_default(lt_preloaded_symbols); - //lt_dlpreload(0); - //lt_dlpreload_open("@PROGRAM@", &ModuleManager::preopenCallback); - application->getConfigManager()->registerConfigurable(this); } ModuleManager::~ModuleManager() { application->getConfigManager()->unregisterConfigurable(this); + boost::shared_lock lock(mutex); while(!moduleOrder.empty()) { - unloadModule(moduleOrder.top()); + std::string mod = moduleOrder.top(); + + lock.unlock(); + unloadModule(mod); + lock.lock(); + moduleOrder.pop(); } - - lt_dlexit(); } bool ModuleManager::handleConfigEntry(const Core::ConfigEntry &entry, bool handled) { @@ -73,38 +65,55 @@ bool ModuleManager::handleConfigEntry(const Core::ConfigEntry &entry, bool handl return false; } -lt_dlhandle ModuleManager::loadModule(const std::string &name) { - std::map >::iterator mod = modules.find(name); +bool ModuleManager::loadModule(const std::string &name) { + { + boost::shared_lock lock(mutex); - if(mod == modules.end()) { - lt_dlhandle handle = lt_dlopen((name + MODULE_SUFFIX).c_str()); + if(modules.find(name) != modules.end()) + return true; + } - if(!handle) - return 0; + ModuleHandle handle = dlopen((name + MODULE_SUFFIX).c_str(), RTLD_NOW | RTLD_GLOBAL); - mod = modules.insert(std::make_pair(lt_dlgetinfo(handle)->name, std::make_pair(handle, (Module*)0))).first; + if(!handle) { + application->log(Core::LoggerBase::VERBOSE, std::string("loadModule: Can't open module: ") + std::string(dlerror())); + return false; } - if(!mod->second.second) { - ModuleLoadFunc loader; - *(void**)&loader = lt_dlsym(mod->second.first, (name + "_create").c_str()); - if(!loader) - return 0; + ModuleLoadFunc loader; + *(void**)&loader = dlsym(handle, (name + "_create").c_str()); - mod->second.second = loader(application); + if(!loader) { + application->log(Core::LoggerBase::VERBOSE, "loadModule: Can't open module: Invalid module"); + return false; + } - if(mod->second.second) - moduleOrder.push(name); + Module *mod = loader(application); + + if(!mod) { + application->log(Core::LoggerBase::VERBOSE, "loadModule: Can't open module: Internal module error"); + return false; } - return mod->second.first; + modules.insert(std::make_pair(name, std::make_pair(handle, mod))).first; + moduleOrder.push(name); + + return true; } void ModuleManager::unloadModule(const std::string &name) { - delete modules[name].second; - lt_dlclose(modules[name].first); + boost::upgrade_lock lock(mutex); + + std::map >::iterator mod = modules.find(name); + if(mod == modules.end()) + return; + + boost::upgrade_to_unique_lock upgradeLock(lock); + + delete mod->second.second; + dlclose(mod->second.first); - modules.erase(name); + modules.erase(mod); } } diff --git a/src/Common/ModuleManager.h b/src/Common/ModuleManager.h index eb8c800..9d722c4 100644 --- a/src/Common/ModuleManager.h +++ b/src/Common/ModuleManager.h @@ -23,14 +23,12 @@ #include "Module.h" #include -#include +#include #include #include #include -#include - namespace Mad { namespace Common { @@ -40,14 +38,15 @@ class ModuleManager : public Core::Configurable, private boost::noncopyable { private: friend class Application; - typedef Module* (*ModuleLoadFunc)(Application*); + typedef void *ModuleHandle; + typedef Module *(*ModuleLoadFunc)(Application*); Application *application; - std::map > modules; + std::map > modules; std::stack moduleOrder; - //static int preopenCallback(lt_dlhandle handle); + boost::shared_mutex mutex; ModuleManager(Application *application0); ~ModuleManager(); @@ -58,7 +57,7 @@ class ModuleManager : public Core::Configurable, private boost::noncopyable { virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool handled); public: - lt_dlhandle loadModule(const std::string &name); + bool loadModule(const std::string &name); }; } -- cgit v1.2.3