From 60f1e0a3942adba1505a8d56064b3cc53834045d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 8 Dec 2008 22:03:45 +0100 Subject: Kann jetzt mit preopen ge?ffnete Module laden --- src/Common/ModuleManager.cpp | 46 +++++++++++++++++++++++++++++++------------- src/Common/ModuleManager.h | 6 ++++-- 2 files changed, 37 insertions(+), 15 deletions(-) (limited to 'src/Common') 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 + + +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 >::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 modules; + std::map > modules; std::stack 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()) -- cgit v1.2.3