summaryrefslogtreecommitdiffstats
path: root/src/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/ModuleManager.cpp46
-rw-r--r--src/Common/ModuleManager.h6
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())