/*
* $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 <dlfcn.h>
#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<XDTPModule*>::iterator iter = (aLibrary->module).begin();
std::list<XDTPModule*>::iterator end = (aLibrary->module).end();
for (; iter != end; iter++) {
aLibrary->freeModule(*iter);
}
}
{
std::list<XDTPChecker*>::iterator iter = (aLibrary->checker).begin();
std::list<XDTPChecker*>::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);
}
syntax highlighted by Code2HTML, v. 0.9.1