00001
00002
00003
00004 #include "GaudiKernel/IFactory.h"
00005 #include "GaudiKernel/ISvcLocator.h"
00006 #include "GaudiKernel/IAlgManager.h"
00007 #include "GaudiKernel/ISvcManager.h"
00008 #include "GaudiKernel/ICnvManager.h"
00009 #include "GaudiKernel/IObjManager.h"
00010 #include "GaudiKernel/IAlgFactory.h"
00011 #include "GaudiKernel/ISvcFactory.h"
00012 #include "GaudiKernel/ICnvFactory.h"
00013 #include "GaudiKernel/FactoryTable.h"
00014 #include "GaudiKernel/ObjectFactory.h"
00015 #include "GaudiKernel/MsgStream.h"
00016 #include "DLLClassManager.h"
00017 #include "GaudiKernel/System.h"
00018
00019 #include <iostream>
00020
00021 typedef std::pair<FactoryTable::EntryList*,FactoryTable::EntryList*> TableObject;
00022 class DllTableSpace : public std::map< std::string, TableObject > {
00023 public:
00024 DllTableSpace();
00025 virtual ~DllTableSpace();
00026 void addDll(const std::string& key, FactoryTable::EntryList* list);
00027 FactoryTable::EntryList* shadow(TableObject& key);
00028 };
00029
00030 DllTableSpace::DllTableSpace() {
00031 }
00032
00033 DllTableSpace::~DllTableSpace() {
00034 for ( iterator i = begin(); i != end(); i++ ) {
00035 FactoryTable::EntryList* tab = (*i).second.first;
00036 tab->erase(tab->begin(), tab->end());
00037 delete tab;
00038 tab = (*i).second.second;
00039 tab->erase(tab->begin(), tab->end());
00040 delete tab;
00041 (*i).second.first = (*i).second.second = 0;
00042 }
00043 erase(begin(), end());
00044 }
00045
00046 FactoryTable::EntryList* DllTableSpace::shadow(TableObject& obj) {
00047 obj.second->erase(obj.second->begin(), obj.second->end());
00048 for( FactoryTable::EntryList::iterator it = obj.first->begin(); it != obj.first->end(); it++ ) {
00049 obj.second->push_back(*it);
00050 }
00051 return obj.second;
00052 }
00053
00054 void DllTableSpace::addDll(const std::string& key, FactoryTable::EntryList* list) {
00055 FactoryTable::EntryList* tab = new FactoryTable::EntryList(list->begin(), list->end());
00056 FactoryTable::EntryList* shadow = new FactoryTable::EntryList();
00057 this->insert(value_type(key, TableObject(tab, shadow)));
00058 }
00059
00060 static DllTableSpace s_dllTableSpace;
00061
00062
00063 DLLClassManager::DLLClassManager( ISvcLocator* svclocator ) {
00064 m_svclocator = svclocator;
00065 m_msgsvc = 0;
00066 m_algmanager = 0;
00067 m_svcmanager = 0;
00068 m_cnvmanager = 0;
00069 m_objmanager = 0;
00070 m_refcount = 1;
00071 }
00072
00073
00074 DLLClassManager::~DLLClassManager() {
00075 }
00076
00077
00078 StatusCode DLLClassManager::declareFactory( const IFactory& factory ) {
00079
00080 StatusCode sc;
00081 IFactory& fact = const_cast<IFactory&>(factory);
00082
00083 IAlgFactory* algfactory = 0;
00084 sc = fact.queryInterface( IID_IAlgFactory, (void**)&algfactory );
00085 if( sc.isSuccess() ) {
00086 if( m_algmanager == 0 ) {
00087 sc = m_svclocator->queryInterface( IID_IAlgManager, (void**)&m_algmanager );
00088 if( sc.isFailure() ) return sc;
00089 }
00090
00091 return m_algmanager->declareAlgFactory( *algfactory, algfactory->algType() );
00092 }
00093
00094 ISvcFactory* svcfactory = 0;
00095 sc = fact.queryInterface( IID_ISvcFactory, (void**)&svcfactory );
00096 if( sc.isSuccess() ) {
00097 if( m_svcmanager == 0 ) {
00098 sc = m_svclocator->queryInterface( IID_ISvcManager, (void**)&m_svcmanager );
00099 if( sc.isFailure() ) return sc;
00100 }
00101
00102 return m_svcmanager->declareSvcFactory( *svcfactory, svcfactory->svcType() );
00103 }
00104
00105 ICnvFactory* cnvfactory = 0;
00106 sc = fact.queryInterface( IID_ICnvFactory, (void**)&cnvfactory );
00107 if( sc.isSuccess() ) {
00108 if( m_cnvmanager == 0 ) {
00109 sc = m_svclocator->queryInterface( IID_ICnvManager, (void**)&m_cnvmanager );
00110 if( sc.isFailure() ) return sc;
00111 }
00112 return m_cnvmanager->declareCnvFactory( *cnvfactory );
00113 }
00114
00115
00116 if( m_objmanager == 0 ) {
00117 sc = m_svclocator->queryInterface( IID_IObjManager, (void**)&m_objmanager );
00118 if( sc.isFailure() ) return sc;
00119 }
00120 return m_objmanager->declareObjFactory( factory );
00121 }
00122
00123
00124 StatusCode DLLClassManager::loadModule( const std::string& module ) {
00125
00126 if( m_msgsvc == 0 ) {
00127 m_svclocator->getService( "MessageSvc", IID_IMessageSvc, (IInterface*&)m_msgsvc );
00128 }
00129 MsgStream log(m_msgsvc, "DllClassManager");
00130
00131 std::string mod = module=="" ? System::moduleNameFull() : module;
00132 if( module == "NONE" ) return StatusCode::SUCCESS;
00133
00134 FactoryTable::EntryList* elist = 0;
00135 DllTableSpace::iterator tabIt = s_dllTableSpace.find(mod);
00136 if ( tabIt != s_dllTableSpace.end() ) {
00137 elist = s_dllTableSpace.shadow((*tabIt).second);
00138 }
00139 else if ( module.length() == 0) {
00140
00141 elist = FactoryTable::instance()->getEntries();
00142 if ( 0 != elist ) s_dllTableSpace.addDll(mod, elist);
00143 }
00144 else {
00145 void* libHandle = 0;
00146 StatusCode status = System::loadDynamicLib( module, &libHandle);
00147 if ( status.isSuccess() ) {
00148 FactoryTable::GetFunction func;
00149 status = System::getProcedureByName(libHandle, "getFactoryEntries", (System::Creator*)&func);
00150 if ( status.isSuccess() ) {
00151 elist = (func)();
00152 if ( 0 != elist ) s_dllTableSpace.addDll(mod, elist);
00153 }
00154 else {
00155
00156 log << MSG::ERROR << "Not found entry point" << endreq;
00157 return StatusCode::FAILURE;
00158 }
00159 }
00160 else {
00161
00162 log << MSG::ERROR << "Not found DLL " << module << endreq;
00163 return StatusCode::FAILURE;
00164 }
00165 }
00166 if( elist == 0 ) return StatusCode::FAILURE;
00167
00168 long num = 0;
00169 for( FactoryTable::EntryList::iterator it = elist->begin(); it != elist->end(); it++ ) {
00170 if( m_msgsvc ) {
00171 log << MSG::DEBUG << "Found factory " << (*it)->ident() << endreq;
00172 }
00173 declareFactory( *(*it) );
00174 num++;
00175 }
00176 if( m_msgsvc ) {
00177 log << MSG::INFO << "Loaded " << num << " factories from module "
00178 << ( (module == "")? System::moduleNameFull() : module ) << endreq;
00179 }
00180
00181
00182 elist->erase( elist->begin(), elist->end() );
00183 return StatusCode::SUCCESS;
00184 }
00185
00186
00187 unsigned long DLLClassManager::addRef() {
00188 m_refcount++;
00189 return m_refcount;
00190 }
00191
00192
00193 unsigned long DLLClassManager::release() {
00194 m_refcount--;
00195 if( m_refcount <= 0) {
00196 delete this;
00197 }
00198 return m_refcount;
00199 }
00200
00201
00202 StatusCode DLLClassManager::queryInterface(const IID& iid, void** pinterface) {
00203 if( iid == IID_IInterface ) {
00204 *pinterface = (IInterface*)this;
00205 }
00206 else if ( iid == IID_IClassManager ) {
00207 *pinterface = (IClassManager*)this;
00208 }
00209 else if ( iid == IID_IInterface ) {
00210 *pinterface = (IInterface*)this;
00211 }
00212 else {
00213 return StatusCode::FAILURE;
00214 }
00215 addRef();
00216 return StatusCode::SUCCESS;
00217 }
00218
00219
00220
00221