/* * $Id: XDTPModuleLoader.cpp,v 1.11 2006/06/30 05:09:11 ozawa Exp $ * * Copyright 2005- ONGS Inc. All rights reserved. * * author: Masanori OZAWA (ozawa@ongs.co.jp) * version: $Revision: 1.11 $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the ONGS Inc. * */ #include "xdtp.h" #include "modules/XDTPModuleLoader.h" #include #define BUILDMODULE_SYM "buildXDTPModule" #define BUILDCHECKER_SYM "buildXDTPChecker" #define FREEMODULE_SYM "freeXDTPModule" #define FREECHECKER_SYM "freeXDTPChecker" #define GETMODULE_VERSION_SYM "getXDTPModuleVersion" using namespace XDTP; XDTPModuleLoader::XDTPModuleLoader() { } XDTPModuleLoader::~XDTPModuleLoader() { } /** * XDTPModuleを内包するライブラリをロードします。 * * @param aPath XDTPModuleを内包するダイナミックリンクライブラリへのパス * @return XDTPModuleを内包するライブラリ。 * 不要になった段階で、unloadModuleLibraryする必要があります。 */ XDTPModuleLibrary* XDTPModuleLoader::loadModuleLibrary(const Glib::ustring& aPath) { void* handle = dlopen(aPath.c_str(), RTLD_NOW | RTLD_GLOBAL); if (!handle) { fprintf(stderr, "%s: %s" LINE_SEP, APP_NAME, dlerror()); return NULL; } XDTPModuleLibrary* lib = new XDTPModuleLibrary; if (!lib) { dlclose(handle); } lib->handle = handle; lib->buildModule = (XDTPModule*(*)())dlsym(handle, BUILDMODULE_SYM); lib->buildChecker = (XDTPChecker*(*)())dlsym(handle, BUILDCHECKER_SYM); lib->freeModule = (void(*)(XDTPModule*))dlsym(handle, FREEMODULE_SYM); lib->freeChecker = (void(*)(XDTPChecker*))dlsym(handle, FREECHECKER_SYM); lib->getModuleVersion = (u_int32_t(*)())dlsym(handle, GETMODULE_VERSION_SYM); #ifdef DEBUG fprintf(stdout, "%s: module load result:" LINE_SEP, APP_NAME); fprintf(stdout, "\t handle: %p" LINE_SEP, lib->handle); fprintf(stdout, "\t buildModule: %p" LINE_SEP, lib->buildModule); fprintf(stdout, "\t buildChecker: %p" LINE_SEP, lib->buildChecker); fprintf(stdout, "\t freeModule: %p" LINE_SEP, lib->freeModule); fprintf(stdout, "\t freeChecker: %p" LINE_SEP, lib->freeChecker); fprintf(stdout, "\t getModuleVersion: %p (%x)" LINE_SEP, lib->getModuleVersion, (lib->getModuleVersion ? lib->getModuleVersion() : 0)); #endif if (!lib->getModuleVersion || (!lib->buildModule || !lib->freeModule) || (lib->buildChecker && !lib->freeChecker)) { dlclose(handle); delete lib; lib = NULL; } return lib; } /** * XDTPModuleを内包するライブラリを解放します。 * 未解放のXDTPModule と XDTPCheckerが存在する場合は、これを解放します。 * * @param aLibrary XDTPModuleを内包するライブラリ。 */ void XDTPModuleLoader::unloadModuleLibrary(XDTPModuleLibrary* aLibrary) { if (!aLibrary) { THROW("bad argument."); } { std::list::iterator iter = (aLibrary->module).begin(); std::list::iterator end = (aLibrary->module).end(); for (; iter != end; iter++) { aLibrary->freeModule(*iter); } } { std::list::iterator iter = (aLibrary->checker).begin(); std::list::iterator end = (aLibrary->checker).end(); for (; iter != end; iter++) { aLibrary->freeChecker(*iter); } } dlclose(aLibrary->handle); delete aLibrary; } /** * XDTPModuleを構築します。 * * @param aLibrary XDTPModuleを内包するライブラリ。 * @return XDTPModuleを戻します。不要になった段階で freeModule する必要があります。 */ XDTPModule* XDTPModuleLoader::buildModule(XDTPModuleLibrary* aLibrary) { u_int32_t version; if (!aLibrary) { THROW("bad argument."); } version = aLibrary->getModuleVersion(); if (XDTP_MODULE_VERSION != version) { #ifdef DEBUG fprintf(stderr, "%s: error: XDTPModule is old. (version=%x)" LINE_SEP, APP_NAME, version); #endif return NULL; } XDTPModule* result = (XDTPModule*)aLibrary->buildModule(); if (result) { (aLibrary->module).push_back(result); } return result; } /** * XDTPCheckerを構築します。 * * @param aLibrary XDTPCheckerを内包するライブラリ。 * @return XDTPCheckerを戻します。不要になった段階で freeChecker する必要があります。 */ XDTPChecker* XDTPModuleLoader::buildChecker(XDTPModuleLibrary* aLibrary) { u_int32_t version; if (!aLibrary) { THROW("bad argument."); } version = aLibrary->getModuleVersion(); if (XDTP_MODULE_VERSION != version) { #ifdef DEBUG fprintf(stderr, "%s: error: XDTPModule is old. (version=%x)" LINE_SEP, APP_NAME, version); #endif return NULL; } if (!aLibrary->buildChecker) { return NULL; } XDTPChecker* result = (XDTPChecker*)aLibrary->buildChecker(); if (result) { (aLibrary->checker).push_back(result); } return result; } /** * XDTPModuleを解放します。 * * @param aLibrary XDTPModuleを内包するライブラリ。 * @param aModule 構築したXDTPModule */ void XDTPModuleLoader::freeModule(XDTPModuleLibrary* aLibrary, XDTPModule* aModule) { if (!aLibrary || !aModule) { THROW("bad argument."); } aLibrary->freeModule(aModule); (aLibrary->module).remove(aModule); } /** * XDTPCheckerを解放します。 * * @param aLibrary XDTPCheckerを内包するライブラリ。 * @param aModule 構築したXDTPChecker */ void XDTPModuleLoader::freeChecker(XDTPModuleLibrary* aLibrary, XDTPChecker* aChecker) { if (!aLibrary || !aChecker) { THROW("bad argument."); } aLibrary->freeChecker(aChecker); (aLibrary->checker).remove(aChecker); }