summaryrefslogtreecommitdiffstats
path: root/src/Common
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-07-01 20:45:25 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-07-01 20:45:25 +0200
commitfd68c0f047bbd40d02cad5a84584cc74979c993a (patch)
tree1c4b3f4a66d08ceed9cdf2f862a0222610a5b27f /src/Common
parent664b4dd6ebfac5cb3bf3412a6d81a8f04b8d23b3 (diff)
downloadmad-fd68c0f047bbd40d02cad5a84584cc74979c993a.tar
mad-fd68c0f047bbd40d02cad5a84584cc74979c993a.zip
ModuleManager: Benutze libdl anstatt ltdl
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/CMakeLists.txt3
-rw-r--r--src/Common/ModuleManager.cpp79
-rw-r--r--src/Common/ModuleManager.h13
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);
};
}