diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | src/Common/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Common/ModuleManager.cpp | 43 | ||||
-rw-r--r-- | src/Common/ModuleManager.h | 2 | ||||
-rw-r--r-- | src/modules/CMakeLists.txt | 47 | ||||
-rw-r--r-- | src/modules/FileLogger/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/modules/SystemBackendPosix/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/modules/SystemBackendProc/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/modules/UserBackendMysql/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/modules/modules.cpp.in | 50 | ||||
-rw-r--r-- | src/modules/modules.h | 39 |
11 files changed, 172 insertions, 23 deletions
@@ -11,6 +11,8 @@ Makefile /.settings /config.h +/src/modules/modules.cpp + /src/mad /src/madc /src/mad-server diff --git a/src/Common/CMakeLists.txt b/src/Common/CMakeLists.txt index 6076561..1ac7e69 100644 --- a/src/Common/CMakeLists.txt +++ b/src/Common/CMakeLists.txt @@ -26,4 +26,4 @@ add_library(Common UserManager.cpp UserManager.h XmlPacket.cpp XmlPacket.h ) -target_link_libraries(Common Backends RequestHandlers Requests Net ${LIBXML2_LIBRARIES} ${DL_LIBRARY}) +target_link_libraries(Common Backends RequestHandlers Requests Net modules ${LIBXML2_LIBRARIES} ${DL_LIBRARY}) diff --git a/src/Common/ModuleManager.cpp b/src/Common/ModuleManager.cpp index 74c424d..67a1b14 100644 --- a/src/Common/ModuleManager.cpp +++ b/src/Common/ModuleManager.cpp @@ -26,12 +26,16 @@ #include <Core/ConfigEntry.h> #include <Core/ConfigManager.h> +#include <modules/modules.h> + #include <dlfcn.h> namespace Mad { namespace Common { +const ModuleManager::ModuleHandle ModuleManager::STATIC_MODULE = 0; + ModuleManager::ModuleManager(Application *application0) : application(application0) { application->getConfigManager()->registerConfigurable(this); } @@ -73,26 +77,31 @@ bool ModuleManager::loadModule(const std::string &name) { return true; } - ModuleHandle handle = dlopen((name + MODULE_SUFFIX).c_str(), RTLD_NOW | RTLD_GLOBAL); + ModuleHandle handle = STATIC_MODULE; + Module *mod = Modules::loadStaticModule(application, name); - if(!handle) { - application->log(Core::LoggerBase::VERBOSE, std::string("loadModule: Can't open module: ") + std::string(dlerror())); - return false; - } + if(!mod) { + handle = dlopen((name + MODULE_SUFFIX).c_str(), RTLD_NOW | RTLD_GLOBAL); - ModuleLoadFunc loader; - *(void**)&loader = dlsym(handle, (name + "_create").c_str()); + if(!handle) { + application->log(Core::LoggerBase::VERBOSE, std::string("loadModule: Can't open module: ") + std::string(dlerror())); + return false; + } - if(!loader) { - application->log(Core::LoggerBase::VERBOSE, "loadModule: Can't open module: Invalid module"); - return false; - } + ModuleLoadFunc loader; + *(void**)&loader = dlsym(handle, (name + "_create").c_str()); - Module *mod = loader(application); + if(!loader) { + application->log(Core::LoggerBase::VERBOSE, "loadModule: Can't open module: Invalid module"); + return false; + } - if(!mod) { - application->log(Core::LoggerBase::VERBOSE, "loadModule: Can't open module: Internal module error"); - return false; + Module *mod = loader(application); + + if(!mod) { + application->log(Core::LoggerBase::VERBOSE, "loadModule: Can't open module: Internal module error"); + return false; + } } modules.insert(std::make_pair(name, std::make_pair(handle, mod))).first; @@ -111,7 +120,9 @@ void ModuleManager::unloadModule(const std::string &name) { boost::upgrade_to_unique_lock<boost::shared_mutex> upgradeLock(lock); delete mod->second.second; - dlclose(mod->second.first); + + if(mod->second.first != STATIC_MODULE) + dlclose(mod->second.first); modules.erase(mod); } diff --git a/src/Common/ModuleManager.h b/src/Common/ModuleManager.h index 9d722c4..8149824 100644 --- a/src/Common/ModuleManager.h +++ b/src/Common/ModuleManager.h @@ -41,6 +41,8 @@ class ModuleManager : public Core::Configurable, private boost::noncopyable { typedef void *ModuleHandle; typedef Module *(*ModuleLoadFunc)(Application*); + static const ModuleHandle STATIC_MODULE; + Application *application; std::map<std::string, std::pair<ModuleHandle, Module*> > modules; diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index ea05a95..4c86688 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -1,5 +1,35 @@ +include_directories(${INCLUDES}) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MAD_BINARY_DIR}/src/modules) -set(CMAKE_SHARED_MODULE_PREFIX "") + +set(STATIC_MODULES "") + +macro(mad_module name) + string(TOUPPER ${name} upper_name) + + set(WITH_${upper_name} ON CACHE BOOL "Enable module '${name}'") + + mark_as_advanced(WITH_STATIC_${upper_name}) + set(WITH_STATIC_${upper_name} OFF CACHE BOOL "Link module '${name}' statically") + + if(WITH_${upper_name}) + if(WITH_STATIC_${upper_name}) + add_library(${name} STATIC ${ARGN}) + set(STATIC_MODULES ${STATIC_MODULES} ${name} PARENT_SCOPE) + else(WITH_STATIC_${upper_name}) + add_library(${name} MODULE ${ARGN}) + set_property(TARGET ${name} PROPERTY PREFIX "") + endif(WITH_STATIC_${upper_name}) + endif(WITH_${upper_name}) +endmacro(mad_module) + +macro(mad_module_libraries name) + string(TOUPPER ${name} upper_name) + + if(WITH_${upper_name}) + target_link_libraries(${name} ${ARGN}) + endif(WITH_${upper_name}) +endmacro(mad_module_libraries) add_subdirectory(FileLogger) add_subdirectory(SystemBackendPosix) @@ -8,3 +38,18 @@ add_subdirectory(SystemBackendProc) if(MYSQL_FOUND) add_subdirectory(UserBackendMysql) endif(MYSQL_FOUND) + +SET(STATIC_MODULE_LOADERS "") +SET(STATIC_MODULE_LIST "") + +foreach(module ${STATIC_MODULES}) + SET(STATIC_MODULE_LOADERS "${STATIC_MODULE_LOADERS}Mad::Common::Module* ${module}_create(Mad::Common::Application *application);\n") + SET(STATIC_MODULE_LIST "${STATIC_MODULE_LIST}std::make_pair(\"${module}\", &${module}_create),\n") +endforeach(module ${STATIC_MODULES}) + +configure_file(modules.cpp.in ${MAD_BINARY_DIR}/src/modules/modules.cpp) + +add_library(modules STATIC + modules.cpp modules.h +) +target_link_libraries(modules ${STATIC_MODULES}) diff --git a/src/modules/FileLogger/CMakeLists.txt b/src/modules/FileLogger/CMakeLists.txt index 555425d..2f654e8 100644 --- a/src/modules/FileLogger/CMakeLists.txt +++ b/src/modules/FileLogger/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(${INCLUDES}) -add_library(FileLogger MODULE +mad_module(FileLogger FileLogger.h Module.cpp Module.h ) diff --git a/src/modules/SystemBackendPosix/CMakeLists.txt b/src/modules/SystemBackendPosix/CMakeLists.txt index 83e8ea1..0cd493d 100644 --- a/src/modules/SystemBackendPosix/CMakeLists.txt +++ b/src/modules/SystemBackendPosix/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(${INCLUDES}) -add_library(SystemBackendPosix MODULE +mad_module(SystemBackendPosix Module.cpp Module.h SystemBackendPosix.cpp SystemBackendPosix.h ) diff --git a/src/modules/SystemBackendProc/CMakeLists.txt b/src/modules/SystemBackendProc/CMakeLists.txt index 42f7431..5341f89 100644 --- a/src/modules/SystemBackendProc/CMakeLists.txt +++ b/src/modules/SystemBackendProc/CMakeLists.txt @@ -1,6 +1,6 @@ include_directories(${INCLUDES}) -add_library(SystemBackendProc MODULE +mad_module(SystemBackendProc Module.cpp Module.h SystemBackendProc.cpp SystemBackendProc.h ) diff --git a/src/modules/UserBackendMysql/CMakeLists.txt b/src/modules/UserBackendMysql/CMakeLists.txt index 5f32d9c..1c71816 100644 --- a/src/modules/UserBackendMysql/CMakeLists.txt +++ b/src/modules/UserBackendMysql/CMakeLists.txt @@ -1,8 +1,8 @@ include_directories(${INCLUDES} ${MYSQL_INCLUDE_DIR}) -add_library(UserBackendMysql MODULE +mad_module(UserBackendMysql Module.cpp Module.h UserBackendMysql.cpp UserBackendMysql.h ) -target_link_libraries(UserBackendMysql ${MYSQL_LIBRARIES})
\ No newline at end of file +mad_module_libraries(UserBackendMysql ${MYSQL_LIBRARIES})
\ No newline at end of file diff --git a/src/modules/modules.cpp.in b/src/modules/modules.cpp.in new file mode 100644 index 0000000..e3feba1 --- /dev/null +++ b/src/modules/modules.cpp.in @@ -0,0 +1,50 @@ +/* + * modules.cpp.in + * + * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "modules.h" + +#include <map> + +extern "C" { +@STATIC_MODULE_LOADERS@ +} + +namespace Mad { +namespace Modules { + +typedef Common::Module *(*ModuleLoadFunc)(Common::Application*); + +static const std::pair<const char*, const ModuleLoadFunc> modules[] = { +@STATIC_MODULE_LIST@ +}; + +static const std::map<const std::string, const ModuleLoadFunc> moduleMap(modules, modules+sizeof(modules)); + +Common::Module* loadStaticModule(Common::Application *application, const std::string &name) { + std::map<const std::string, const ModuleLoadFunc>::const_iterator it = moduleMap.find(name); + + if(it == moduleMap.end()) + return 0; + + else + return it->second(application); +} + +} +} diff --git a/src/modules/modules.h b/src/modules/modules.h new file mode 100644 index 0000000..e992b2d --- /dev/null +++ b/src/modules/modules.h @@ -0,0 +1,39 @@ +/* + * modules.h + * + * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MAD_MODULES_H_ +#define MAD_MODULES_H_ + +#include <string> + +namespace Mad { + +namespace Common { +class Application; +class Module; +} + +namespace Modules { + +Common::Module* loadStaticModule(Common::Application *application, const std::string &name); + +} +} + +#endif /* MAD_MODULES_H_ */ |