diff options
Diffstat (limited to 'src/Common/ModuleManager.cpp')
-rw-r--r-- | src/Common/ModuleManager.cpp | 46 |
1 files changed, 33 insertions, 13 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); } |