From ae896d73d4914fa96f053a0443f6b05003c12b35 Mon Sep 17 00:00:00 2001 From: Alan Conway Date: Wed, 4 Jul 2007 03:24:48 +0000 Subject: 2007-07-02 -#include -#include - -namespace qpid { -namespace sys { - -typedef apr_dso_handle_t* dso_handle_t; - -template class Module : private boost::noncopyable -{ - typedef T* create_t(); - typedef void destroy_t(T*); - - dso_handle_t handle; - destroy_t* destroy; - T* ptr; - - void load(const std::string& name); - void unload(); - void* getSymbol(const std::string& name); - -public: - Module(const std::string& name); - T* operator->(); - T* get(); - ~Module() throw(); -}; - -template Module::Module(const std::string& module) : destroy(0), ptr(0) -{ - load(module); - //TODO: need a better strategy for symbol names to allow multiple - //modules to be loaded without clashes... - - //Note: need the double cast to avoid errors in casting from void* to function pointer with -pedantic - create_t* create = reinterpret_cast(reinterpret_cast(getSymbol("create"))); - destroy = reinterpret_cast(reinterpret_cast(getSymbol("destroy"))); - ptr = create(); -} - -template T* Module::operator->() -{ - return ptr; -} - -template T* Module::get() -{ - return ptr; -} - -template Module::~Module() throw() -{ - try { - if (handle && ptr) { - destroy(ptr); - } - if (handle) unload(); - } catch (std::exception& e) { - QPID_LOG(error, "Error while destroying module: " << e.what()); - } - destroy = 0; - handle = 0; - ptr = 0; -} - -template void Module::load(const std::string& name) -{ - CHECK_APR_SUCCESS(apr_dso_load(&handle, name.c_str(), APRPool::get())); -} - -template void Module::unload() -{ - CHECK_APR_SUCCESS(apr_dso_unload(handle)); -} - -template void* Module::getSymbol(const std::string& name) -{ - apr_dso_handle_sym_t symbol; - CHECK_APR_SUCCESS(apr_dso_sym(&symbol, handle, name.c_str())); - return (void*) symbol; -} - -}} -#endif //ifndef _sys_apr_Module_h - -- cgit v1.2.1