![]() |
|
|
Generated: 18 Jul 2008 |
00001 //$Id: Bootstrap.cpp,v 1.14 2007/12/12 16:02:32 marcocle Exp $ 00002 00003 #include <iostream> 00004 00005 #include "GaudiKernel/Bootstrap.h" 00006 #include "GaudiKernel/System.h" 00007 00008 #include "GaudiKernel/IInterface.h" 00009 #include "GaudiKernel/IAlgorithm.h" 00010 #include "GaudiKernel/IService.h" 00011 #include "GaudiKernel/IAppMgrUI.h" 00012 #include "GaudiKernel/ISvcLocator.h" 00013 #include "GaudiKernel/IClassManager.h" 00014 00015 #include "Reflex/PluginService.h" 00016 using ROOT::Reflex::PluginService; 00017 00018 00019 namespace Gaudi 00020 { 00021 00037 class BootSvcLocator : virtual public ISvcLocator { 00038 public: 00039 BootSvcLocator(); 00040 virtual ~BootSvcLocator(); 00042 virtual unsigned long addRef(); 00044 virtual unsigned long release(); 00046 virtual StatusCode queryInterface(const InterfaceID& iid, void** pinterface); 00047 virtual StatusCode getService( const std::string& name, 00048 IService*& svc ); 00049 virtual StatusCode getService( const std::string& name, 00050 const InterfaceID& iid, 00051 IInterface*& pinterface ); 00052 virtual StatusCode getService( const std::string& name, 00053 IService*& svc, 00054 bool createIf ); 00055 virtual const std::list<IService*>& getServices( ) const; 00056 virtual bool existsService( const std::string& name ) const; 00057 private: 00058 unsigned long m_refcount; 00059 }; 00060 } 00061 00062 00063 static ISvcLocator* s_svclocInstance = 0; 00064 static IAppMgrUI* s_appmgrInstance = 0; 00065 00066 //------------------------------------------------------------------------------ 00067 IAppMgrUI* Gaudi::createApplicationMgr(const std::string& dllname, 00068 const std::string& factname) 00069 //------------------------------------------------------------------------------ 00070 { 00071 // Allow not for multiple AppManagers: If already instantiated then just 00072 // return it 00073 if ( 0 == s_appmgrInstance ) { 00074 s_appmgrInstance = createApplicationMgrEx(dllname, factname); 00075 StatusCode sc = s_appmgrInstance->queryInterface( IID_ISvcLocator, 00076 pp_cast<void>(&s_svclocInstance) ); 00077 } 00078 return s_appmgrInstance; 00079 } 00080 00081 //------------------------------------------------------------------------------ 00082 IAppMgrUI* Gaudi::createApplicationMgrEx(const std::string& dllname, 00083 const std::string& factname) 00084 //------------------------------------------------------------------------------ 00085 { 00086 StatusCode status; 00087 IInterface* iif; 00088 IAppMgrUI* iappmgr; 00089 00090 // Create an instance of the application Manager 00091 iif = Gaudi::createInstance( "ApplicationMgr", factname, dllname ); 00092 if( iif == 0 ) { 00093 return 0; 00094 } 00095 // Locate few interfaces of the Application Manager 00096 status = iif->queryInterface( IID_IAppMgrUI, pp_cast<void>(&iappmgr) ); 00097 if( status.isFailure() ) { 00098 return 0; 00099 } 00100 iif->release(); 00101 return iappmgr; 00102 } 00103 00104 //------------------------------------------------------------------------------ 00105 ISvcLocator* Gaudi::svcLocator() 00106 //------------------------------------------------------------------------------ 00107 // 00108 // A dual-stage boostrap mechanism is used to ensure an orderly startup 00109 // of the ApplicationMgr. If this function is called before the singleton 00110 // ApplicationMgr instance exists, a BootSvcLocator singleton instance is 00111 // created. This responds to any subsequent requests for services by 00112 // returning StatusCode::FAILURE, unless the ApplicationMgr singleton 00113 // instance has been created in the interim. In this case, the BootSvcLocator 00114 // forwards the request to the ApplicationMgr instance. The motiviation for 00115 // this is to handle static object instances where the constructor attempts 00116 // to locate services and would otherwise instantiate the ApplicationMgr 00117 // instance in an unorderly manner. This logic requires that the 00118 // ApplicationMgr instance is created explicitly. 00119 00120 { 00121 if( 0 == s_svclocInstance ) { 00122 IAppMgrUI* iappmgr = createApplicationMgr(); 00123 if( iappmgr ) { 00124 StatusCode sc = iappmgr->queryInterface( IID_ISvcLocator, 00125 pp_cast<void>(&s_svclocInstance) ); 00126 if( sc.isSuccess() ) { 00127 return s_svclocInstance; 00128 } 00129 } 00130 //---Reverted change to create a Minimal SvcLocator in case is requested before AppMgr is created 00131 //if( 0 == s_appmgrInstance ) { 00132 // s_svclocInstance = new BootSvcLocator(); 00133 //} else { 00134 // StatusCode sc = s_appmgrInstance->queryInterface( IID_ISvcLocator, 00135 // pp_cast<void>(&s_svclocInstance) ); 00136 // if( sc.isSuccess() ) { 00137 // return s_svclocInstance; 00138 // } 00139 //} 00140 } 00141 return s_svclocInstance; 00142 } 00143 00144 //------------------------------------------------------------------------------ 00145 ISvcLocator* Gaudi::setInstance(ISvcLocator* newInstance) 00146 //------------------------------------------------------------------------------ 00147 { 00148 ISvcLocator* oldInstance = s_svclocInstance; 00149 s_svclocInstance = newInstance; 00150 if ( s_appmgrInstance ) { 00151 s_appmgrInstance->release(); 00152 s_appmgrInstance = 0; 00153 } 00154 if ( s_svclocInstance ) { 00155 s_svclocInstance->queryInterface (IID_IAppMgrUI, pp_cast<void>(&s_appmgrInstance)); 00156 } 00157 return oldInstance; 00158 } 00159 00160 //------------------------------------------------------------------------------ 00161 IAppMgrUI* Gaudi::setInstance(IAppMgrUI* newInstance) 00162 //------------------------------------------------------------------------------ 00163 { 00164 IAppMgrUI* oldInstance = s_appmgrInstance; 00165 s_appmgrInstance = newInstance; 00166 if ( s_svclocInstance ) { 00167 s_svclocInstance->release(); 00168 s_svclocInstance = 0; 00169 } 00170 if ( s_appmgrInstance ) { 00171 s_appmgrInstance->queryInterface (IID_ISvcLocator, 00172 pp_cast<void>(&s_svclocInstance)); 00173 } 00174 return oldInstance; 00175 } 00176 00177 //------------------------------------------------------------------------------ 00178 IInterface* Gaudi::createInstance( const std::string& name, 00179 const std::string& factname, 00180 const std::string& dllname) 00181 //------------------------------------------------------------------------------ 00182 { 00183 00184 IInterface* ii = PluginService::Create<IInterface*>(factname,(IInterface*)0); 00185 if ( ii ) return ii; 00186 IService* is = PluginService::Create<IService*>(factname, name, (ISvcLocator*)0); 00187 if ( is ) return is; 00188 IAlgorithm* ia = PluginService::Create<IAlgorithm*>(factname, name, (ISvcLocator*)0); 00189 if ( ia ) return ia; 00190 00191 StatusCode status; 00192 void* libHandle = 0; 00193 status = System::loadDynamicLib( dllname, &libHandle); 00194 if ( status.isSuccess() ) { 00195 IInterface* ii = PluginService::Create<IInterface*>(factname, (IInterface*)0); 00196 if ( ii ) return ii; 00197 IService* is = PluginService::Create<IService*>(factname, name, (ISvcLocator*)0); 00198 if ( is ) return is; 00199 IAlgorithm* ia = PluginService::Create<IAlgorithm*>(factname, name, (ISvcLocator*)0); 00200 if ( ia ) return ia; 00201 00202 return 0; 00203 } 00204 else { 00205 // DLL library not loaded. Try in the local module 00206 std::cout << System::getLastErrorString() << std::endl; 00207 std::cout << "Gaudi::Bootstrap: Not found DLL " << dllname << std::endl; 00208 return 0; 00209 } 00210 } 00211 00212 namespace { 00213 class ShadowEntry { 00214 public: 00215 std::string dllName; 00216 std::string facName; 00217 IFactory* fac; 00218 public: 00219 ShadowEntry() { 00220 } 00221 ShadowEntry(const std::string& d, const std::string& n, const IFactory* f) { 00222 dllName = d; 00223 facName = n; 00224 fac = const_cast<IFactory*>(f); 00225 } 00226 ShadowEntry(const ShadowEntry& copy) { 00227 dllName = copy.dllName; 00228 facName = copy.facName; 00229 fac = copy.fac; 00230 } 00231 ShadowEntry& operator=(const ShadowEntry& copy) { 00232 dllName = copy.dllName; 00233 facName = copy.facName; 00234 fac = copy.fac; 00235 return *this; 00236 } 00237 }; 00238 } 00239 00240 //------------------------------------------------------------------------------ 00241 IAppMgrUI* Gaudi::createApplicationMgr(const std::string& dllname ) { 00242 //------------------------------------------------------------------------------ 00243 return createApplicationMgr(dllname, "ApplicationMgr"); 00244 } 00245 00246 //------------------------------------------------------------------------------ 00247 IAppMgrUI* Gaudi::createApplicationMgr() { 00248 //------------------------------------------------------------------------------ 00249 return createApplicationMgr("GaudiSvc", "ApplicationMgr"); 00250 } 00251 00252 //======================================================================= 00253 // BootSvcLocator 00254 //======================================================================= 00255 00256 static std::list<IService*> s_bootServices; 00257 static IService* s_bootService = 0; 00258 static IInterface* s_bootInterface = 0; 00259 00260 using Gaudi::BootSvcLocator; 00261 00262 BootSvcLocator::BootSvcLocator() { 00263 m_refcount = 0; 00264 } 00265 BootSvcLocator::~BootSvcLocator() { 00266 } 00267 unsigned long BootSvcLocator::addRef() { 00268 m_refcount++; 00269 return m_refcount; 00270 } 00271 unsigned long BootSvcLocator::release() { 00272 unsigned long count = --m_refcount; 00273 if( count <= 0) { 00274 delete this; 00275 } 00276 return count; 00277 } 00278 StatusCode Gaudi::BootSvcLocator::queryInterface(const InterfaceID& iid, void** pinterface) 00279 { 00280 if( iid == IID_IInterface ) { 00281 *pinterface = (IInterface*)this; 00282 addRef(); 00283 return StatusCode::SUCCESS; 00284 } 00285 else if ( iid == IID_ISvcLocator ) { 00286 *pinterface = (ISvcLocator*)this; 00287 addRef(); 00288 return StatusCode::SUCCESS; 00289 } 00290 return StatusCode::FAILURE; 00291 } 00292 StatusCode Gaudi::BootSvcLocator::getService( const std::string& name, 00293 IService*& svc ) { 00294 StatusCode sc = StatusCode::FAILURE; 00295 if ( 0 != s_appmgrInstance ) { 00296 sc = s_svclocInstance->getService(name, svc ); 00297 } else { 00298 svc = s_bootService; 00299 } 00300 return sc; 00301 } 00302 StatusCode Gaudi::BootSvcLocator::getService( const std::string& name, 00303 const InterfaceID& iid, 00304 IInterface*& pinterface ) { 00305 StatusCode sc = StatusCode::FAILURE; 00306 if ( 0 != s_appmgrInstance ) { 00307 sc = s_svclocInstance->getService(name, iid, pinterface ); 00308 } else { 00309 pinterface = s_bootInterface; 00310 } 00311 return sc; 00312 } 00313 StatusCode Gaudi::BootSvcLocator::getService( const std::string& name, 00314 IService*& svc, 00315 bool createIf ) { 00316 StatusCode sc = StatusCode::FAILURE; 00317 if ( 0 != s_appmgrInstance ) { 00318 sc = s_svclocInstance->getService(name, svc, createIf ); 00319 } else { 00320 svc = s_bootService; 00321 } 00322 return sc; 00323 } 00324 const std::list<IService*>& Gaudi::BootSvcLocator::getServices( ) const { 00325 StatusCode sc = StatusCode::FAILURE; 00326 if ( 0 != s_appmgrInstance ) { 00327 return s_svclocInstance->getServices( ); 00328 } else { 00329 return s_bootServices; 00330 } 00331 } 00332 bool Gaudi::BootSvcLocator::existsService( const std::string& name ) const { 00333 bool result = false; 00334 if ( 0 != s_appmgrInstance ) { 00335 result = s_svclocInstance->existsService(name ); 00336 } 00337 return result; 00338 }