diff options
Diffstat (limited to 'src/Common')
-rw-r--r-- | src/Common/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/Common/ModuleManager.cpp | 79 | ||||
-rw-r--r-- | src/Common/ModuleManager.h | 13 |
3 files changed, 51 insertions, 44 deletions
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 <Core/ConfigEntry.h> #include <Core/ConfigManager.h> -//extern const lt_dlsymlist lt_preloaded_symbols[]; +#include <dlfcn.h> 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<boost::shared_mutex> 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<std::string, std::pair<lt_dlhandle, Module*> >::iterator mod = modules.find(name); +bool ModuleManager::loadModule(const std::string &name) { + { + boost::shared_lock<boost::shared_mutex> 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<boost::shared_mutex> lock(mutex); + + std::map<std::string, std::pair<ModuleHandle, Module*> >::iterator mod = modules.find(name); + if(mod == modules.end()) + return; + + boost::upgrade_to_unique_lock<boost::shared_mutex> 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 <Core/Configurable.h> -#include <boost/noncopyable.hpp> +#include <boost/thread/shared_mutex.hpp> #include <map> #include <stack> #include <string> -#include <ltdl.h> - 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<std::string, std::pair<lt_dlhandle, Module*> > modules; + std::map<std::string, std::pair<ModuleHandle, Module*> > modules; std::stack<std::string> 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); }; } |