diff options
Diffstat (limited to 'src/Common')
-rw-r--r-- | src/Common/ModuleManager.cpp | 46 | ||||
-rw-r--r-- | src/Common/ModuleManager.h | 6 |
2 files changed, 37 insertions, 15 deletions
diff --git a/src/Common/ModuleManager.cpp b/src/Common/ModuleManager.cpp index 2df1078..06732a4 100644 --- a/src/Common/ModuleManager.cpp +++ b/src/Common/ModuleManager.cpp @@ -22,14 +22,28 @@ #include "ConfigEntry.h" #include "Logger.h" +#include <iostream> + + +extern const lt_dlsymlist lt_preloaded_symbols[]; + + namespace Mad { namespace Common { ModuleManager ModuleManager::moduleManager; +int ModuleManager::preopenCallback(lt_dlhandle handle) { + moduleManager.modules.insert(std::make_pair(lt_dlgetinfo(handle)->name, std::make_pair(handle, false))); +} + void ModuleManager::doInit() { lt_dlinit(); + + lt_dlpreload_default(lt_preloaded_symbols); + lt_dlpreload(0); + lt_dlpreload_open("@PROGRAM@", &ModuleManager::preopenCallback); } void ModuleManager::doDeinit() { @@ -55,32 +69,38 @@ bool ModuleManager::handleConfigEntry(const ConfigEntry &entry, bool handled) { return false; } -bool ModuleManager::loadModule(const std::string &name) { - lt_dlhandle handle = lt_dlopen(name.c_str()); +lt_dlhandle ModuleManager::loadModule(const std::string &name) { + std::map<std::string, std::pair<lt_dlhandle, bool> >::iterator mod = modules.find(name); - if(!handle) - return false; + if(mod == modules.end()) { + lt_dlhandle handle = lt_dlopen((name + ".la").c_str()); - void (*initFun)(); - initFun = (void(*)())lt_dlsym(handle, "init"); + if(!handle) + return 0; - if(initFun) - (*initFun)(); + mod = modules.insert(std::make_pair(lt_dlgetinfo(handle)->name, std::make_pair(handle, false))).first; + } + if(!mod->second.second) { + void (*initFun)() = (void(*)())lt_dlsym(mod->second.first, "init"); - modules.insert(std::make_pair(name, handle)); - moduleOrder.push(name); + if(initFun) + (*initFun)(); + + mod->second.second = true; + moduleOrder.push(name); + } - return true; + return mod->second.first; } void ModuleManager::unloadModule(const std::string &name) { void (*deinitFun)(); - deinitFun = (void(*)())lt_dlsym(modules[name], "deinit"); + deinitFun = (void(*)())lt_dlsym(modules[name].first, "deinit"); if(deinitFun) (*deinitFun)(); - lt_dlclose(modules[name]); + lt_dlclose(modules[name].first); modules.erase(name); } diff --git a/src/Common/ModuleManager.h b/src/Common/ModuleManager.h index e327f28..fa7316f 100644 --- a/src/Common/ModuleManager.h +++ b/src/Common/ModuleManager.h @@ -36,9 +36,11 @@ class ModuleManager : public Configurable, public Initializable { private: static ModuleManager moduleManager; - std::map<std::string, lt_dlhandle> modules; + std::map<std::string, std::pair<lt_dlhandle, bool> > modules; std::stack<std::string> moduleOrder; + static int preopenCallback(lt_dlhandle handle); + void unloadModule(const std::string &name); protected: @@ -48,7 +50,7 @@ class ModuleManager : public Configurable, public Initializable { virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled); public: - bool loadModule(const std::string &name); + lt_dlhandle loadModule(const std::string &name); static ModuleManager* get() { if(!moduleManager.isInitialized()) |