![]() |
|
|
Generated: 18 Jul 2008 |
00001 // $Id: ServiceManager.cpp,v 1.25 2008/06/06 13:20:49 marcocle Exp $ 00002 00003 // Include files 00004 #include "ServiceManager.h" 00005 #include "GaudiKernel/IService.h" 00006 #include "GaudiKernel/SvcFactory.h" 00007 #include "GaudiKernel/MsgStream.h" 00008 #include "GaudiKernel/ListItem.h" 00009 #include "GaudiKernel/System.h" 00010 #include "GaudiKernel/Service.h" 00011 00012 #include <iostream> 00013 #include <cassert> 00014 00015 using ROOT::Reflex::PluginService; 00016 // constructor 00017 ServiceManager::ServiceManager(IInterface* iface): 00018 m_statemgr(iface) 00019 { 00020 m_refcount = 1; 00021 m_pOuter = iface; 00022 m_svclocator = (ISvcLocator*)this; 00023 m_msgsvc = 0; 00024 } 00025 00026 // destructor 00027 ServiceManager::~ServiceManager() { 00028 if( m_msgsvc ) m_msgsvc->release(); 00029 //-- inform the orphan services that I am gone.... 00030 for (ListSvc::const_iterator it = m_listsvc.begin(); it != m_listsvc.end(); it++ ) { 00031 (*it)->setServiceManager(0); 00032 } 00033 } 00034 00035 // addRef 00036 unsigned long ServiceManager::addRef() { 00037 m_refcount++; 00038 return m_refcount; 00039 } 00040 00041 // release 00042 unsigned long ServiceManager::release() { 00043 unsigned long count = --m_refcount; 00044 if( count <= 0) { 00045 delete this; 00046 } 00047 return count; 00048 } 00049 00050 //------------------------------------------------------------------------------ 00051 StatusCode ServiceManager::queryInterface(const InterfaceID& iid, void** pinterface) 00052 //------------------------------------------------------------------------------ 00053 { 00054 if( iid == IID_IInterface ) { 00055 *pinterface = (IInterface*)this; 00056 addRef(); 00057 return StatusCode::SUCCESS; 00058 } 00059 else if ( iid == IID_ISvcLocator ) { 00060 *pinterface = (ISvcLocator*)this; 00061 addRef(); 00062 return StatusCode::SUCCESS; 00063 } 00064 else if ( iid == IID_ISvcManager ) { 00065 *pinterface = (ISvcManager*)this; 00066 addRef(); 00067 return StatusCode::SUCCESS; 00068 } 00069 else { 00070 return m_pOuter->queryInterface(iid, pinterface); 00071 } 00072 } 00073 00074 //------------------------------------------------------------------------------ 00075 StatusCode ServiceManager::getService( const std::string& name, IService*& svc) 00076 //------------------------------------------------------------------------------ 00077 { 00078 return getService(name, svc, true); 00079 } 00080 //------------------------------------------------------------------------------ 00081 StatusCode ServiceManager::getService( const std::string& name, const InterfaceID& iid, 00082 IInterface*& pinterface) 00083 //------------------------------------------------------------------------------ 00084 { 00085 IService* svc; 00086 StatusCode status = getService( name, svc, false ); 00087 if( status.isSuccess() ) { 00088 // Service found. So now get the right interface 00089 status = svc->queryInterface( iid, (void**)&pinterface ); 00090 } 00091 return status; 00092 } 00093 //------------------------------------------------------------------------------ 00094 StatusCode ServiceManager::makeService( const std::string& nam, 00095 IService*& svc ) 00096 //------------------------------------------------------------------------------ 00097 { 00098 // find out if name is registered with a type 00099 std::string name = nam; 00100 std::string type; 00101 MapType::iterator it = m_maptype.find( nam ); 00102 if( it != m_maptype.end() ) { 00103 type = (*it).second; 00104 } else { 00105 // otherwise parse the name to see if it is of the format "type/name" 00106 ListItem item(name); 00107 type = item.type(); 00108 name = item.name(); 00109 } 00110 std::string::size_type ip; 00111 if ( (ip = type.find("__")) != std::string::npos) { 00112 type.erase(ip,type.length()); 00113 } 00114 StatusCode sc = createService( type, name, svc ); 00115 if( sc.isSuccess() ) { 00116 // Bring the created service to the same state in which the ApplicationMgr 00117 // will be. 00118 if (m_statemgr->targetFSMState() >= Gaudi::StateMachine::INITIALIZED) { 00119 sc = svc->sysInitialize(); 00120 if (sc.isSuccess() && m_statemgr->targetFSMState() >= Gaudi::StateMachine::RUNNING) { 00121 sc = svc->sysStart(); 00122 } 00123 } 00124 00125 if( sc.isSuccess() ) { 00126 sc = addService( svc, 10); 00127 } else { 00128 MsgStream log(msgSvc(), "ServiceManager"); 00129 log << MSG::ERROR << "Unable to initialize service \"" << name << "\"" 00130 << endreq; 00131 removeService(svc).ignore(); //if init fails remove it from the list 00132 delete svc; 00133 svc = 0; 00134 } 00135 if (svc!= 0) svc->setServiceManager( this ); 00136 } 00137 return sc; 00138 } 00139 00140 //------------------------------------------------------------------------------ 00141 StatusCode ServiceManager::getService( const std::string& nam, IService*& svc, 00142 bool createIf) 00143 //------------------------------------------------------------------------------ 00144 { 00145 ListItem item(nam); 00146 const std::string& name = item.name(); 00147 00148 StatusCode sc(StatusCode::FAILURE); 00149 ListSvc::iterator it(m_listsvc.begin()); 00150 for (; it != m_listsvc.end(); ++it ) { 00151 if( (*it)->name() == name ) { 00152 svc = *it; 00153 break; 00154 } 00155 } 00156 00157 if (it != m_listsvc.end()) { 00158 if (createIf && (*it)->FSMState() == Gaudi::StateMachine::CONFIGURED ) { 00159 MsgStream log(msgSvc(), "ServiceManager"); 00160 log << MSG::ERROR 00161 << "Initialization loop detected when creating service \"" << name 00162 << "\"" 00163 << endreq; 00164 sc = StatusCode::FAILURE; 00165 } else { 00166 sc = StatusCode::SUCCESS; 00167 } 00168 } else { 00169 // Service not found. The user may be interested in one of the interfaces 00170 // of the application manager itself 00171 if( name == "ApplicationMgr" || 00172 name == "APPMGR" || 00173 name == "" ) { 00174 sc = m_svclocator->queryInterface( IService::interfaceID(), (void**)&svc ); 00175 if( svc ) svc->release(); // Do not increase the reference count 00176 } else if ( createIf ){ 00177 //last resort: we try to create the service 00178 if ( item.name() != item.type() ) { 00179 // if we were asked for a "ServiceType/ServiceName", we pass the string 00180 // directly to makeService 00181 sc = makeService(nam, svc); 00182 } else { 00183 // the user did not specified both type and name 00184 sc = makeService(name, svc); 00185 } 00186 } 00187 } 00188 00189 return sc; 00190 } 00191 00192 //------------------------------------------------------------------------------ 00193 const std::list<IService*>& ServiceManager::getServices( ) const 00194 //------------------------------------------------------------------------------ 00195 { 00196 return m_listsvc; 00197 } 00198 00199 //------------------------------------------------------------------------------ 00200 std::list<IService*> ServiceManager::getActiveServices( ) const 00201 //------------------------------------------------------------------------------ 00202 { 00203 std::list<IService*> asvcs; 00204 for (PListSvc::const_iterator itr = m_activesvc.begin(); 00205 itr != m_activesvc.end(); ++itr) { 00206 asvcs.push_back( itr->first ); 00207 } 00208 return asvcs; 00209 } 00210 00211 00212 //------------------------------------------------------------------------------ 00213 bool ServiceManager::existsService( const std::string& name) const 00214 //------------------------------------------------------------------------------ 00215 { 00216 ListSvc::const_iterator it; 00217 for (it = m_listsvc.begin(); it != m_listsvc.end(); it++ ) { 00218 if( name == (*it)->name() ) { 00219 return true; 00220 } 00221 } 00222 return false; 00223 } 00224 00225 //------------------------------------------------------------------------------ 00226 StatusCode ServiceManager::addService( IService* svc, int prio ) 00227 //------------------------------------------------------------------------------ 00228 { 00229 PListSvc::iterator it; 00230 // remove it if already in the list 00231 removeActiveService( svc ).ignore(); 00232 // insert in the right place in the list 00233 for( it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00234 if( (*it).second > prio ) break; 00235 } 00236 m_activesvc.insert(it, std::make_pair(svc, prio)); 00237 return StatusCode::SUCCESS; 00238 } 00239 00240 //------------------------------------------------------------------------------ 00241 StatusCode ServiceManager::addService( const std::string& type, 00242 const std::string& name, int prio ) 00243 //------------------------------------------------------------------------------ 00244 { 00245 StatusCode sc; 00246 IService* svc; 00247 if( existsService(name) ) { 00248 sc = getService(name, svc); 00249 } else { 00250 if( type.length() == 0 ) { 00251 // find out if name is registered with a type 00252 MapType::iterator it = m_maptype.find( name ); 00253 if( it != m_maptype.end() ) { 00254 sc = createService( (*it).second, name, svc ); 00255 } else { 00256 sc = createService( name, name, svc ); 00257 } 00258 } else { 00259 sc = createService( type, name, svc ); 00260 } 00261 00262 if (sc.isSuccess() && m_statemgr->targetFSMState() >= Gaudi::StateMachine::INITIALIZED) { 00263 sc = svc->sysInitialize(); 00264 if (sc.isSuccess() && m_statemgr->targetFSMState() >= Gaudi::StateMachine::RUNNING) { 00265 sc = svc->sysStart(); 00266 } 00267 } 00268 00269 } 00270 if( sc.isSuccess() ) { 00271 return addService( svc, prio ); 00272 } 00273 else { 00274 return sc; 00275 } 00276 } 00277 00278 //------------------------------------------------------------------------------ 00279 StatusCode ServiceManager::removeService( IService* svc) 00280 //------------------------------------------------------------------------------ 00281 { 00282 00283 removeActiveService(svc).ignore(); 00284 removeListService(svc).ignore(); 00285 00286 return StatusCode(StatusCode::SUCCESS,true); 00287 } 00288 00289 //------------------------------------------------------------------------------ 00290 StatusCode ServiceManager::removeActiveService( IService* svc) 00291 //------------------------------------------------------------------------------ 00292 { 00293 PListSvc::iterator it; 00294 for (it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00295 if( (*it).first == svc ) { 00296 m_activesvc.erase(it); 00297 break; 00298 } 00299 } 00300 00301 return StatusCode::SUCCESS; 00302 } 00303 00304 //------------------------------------------------------------------------------ 00305 StatusCode ServiceManager::removeListService( IService* svc) 00306 //------------------------------------------------------------------------------ 00307 { 00308 00309 ListSvc::iterator ll; 00310 for ( ll = m_listsvc.begin(); ll != m_listsvc.end(); ++ll ) { 00311 if ( (*ll) == svc ) { 00312 m_listsvc.erase( ll ); 00313 break; 00314 } 00315 } 00316 00317 return StatusCode::SUCCESS; 00318 } 00319 00320 00321 //------------------------------------------------------------------------------ 00322 StatusCode ServiceManager::removeService( const std::string& nam ) 00323 //------------------------------------------------------------------------------ 00324 { 00325 IService* svc; 00326 if( getService(nam, svc).isSuccess() ) return removeService(svc); 00327 else return StatusCode::FAILURE; 00328 } 00329 00330 //------------------------------------------------------------------------------ 00331 StatusCode ServiceManager::declareSvcFactory( const ISvcFactory& factory, 00332 const std::string& svctype ) 00333 //------------------------------------------------------------------------------ 00334 { 00335 00336 std::pair<MapFactory::iterator, bool> p; 00337 p = m_mapfactory.insert(MapFactory::value_type( svctype, (ISvcFactory*)&factory) ); 00338 if( p.second == false) { 00339 MsgStream log(msgSvc(), "ServiceManager"); 00340 log << MSG::WARNING << "Service factory for type " << svctype << " already declared" << endreq; 00341 m_mapfactory.erase ( p.first ); 00342 p = m_mapfactory.insert(MapFactory::value_type( svctype, (ISvcFactory*)&factory) ); 00343 if( p.second == false) return StatusCode::FAILURE; 00344 } 00345 return StatusCode::SUCCESS; 00346 } 00347 00348 //------------------------------------------------------------------------------ 00349 StatusCode ServiceManager::declareSvcType( const std::string& svcname, 00350 const std::string& svctype ) 00351 //------------------------------------------------------------------------------ 00352 { 00353 std::pair<MapType::iterator, bool> p = m_maptype.insert(std::make_pair(svcname, svctype)); 00354 if( p.second == false) { 00355 m_maptype.erase ( p.first ); 00356 p = m_maptype.insert(std::make_pair(svcname, svctype) ); 00357 if( p.second == false) return StatusCode::FAILURE; 00358 } 00359 return StatusCode::SUCCESS; 00360 } 00361 00362 //------------------------------------------------------------------------------ 00363 StatusCode ServiceManager::initializeServices() 00364 //------------------------------------------------------------------------------ 00365 { 00366 StatusCode sc; 00367 MsgStream log(msgSvc(), "ServiceManager"); 00368 00369 // call initialize() for all services 00370 for (PListSvc::iterator it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00371 std::string name = (*it).first->name(); 00372 switch ((*it).first->FSMState()) { 00373 case Gaudi::StateMachine::INITIALIZED: 00374 log << MSG::DEBUG << "Service " << name 00375 << " already initialized" << endreq; 00376 break; 00377 case Gaudi::StateMachine::OFFLINE: 00378 log << MSG::DEBUG << "Initializing service " << name << endreq; 00379 sc = (*it).first->sysInitialize(); 00380 if( !sc.isSuccess() ) { 00381 log << MSG::ERROR << "Unable to initialize Service: " << (*it).first->name() << endreq; 00382 return sc; 00383 } break; 00384 default: 00385 log << MSG::ERROR << "Service " << name 00386 << " not in the correct state to be initialized (" 00387 << (*it).first->FSMState() << ")" << endreq; 00388 return StatusCode::FAILURE; 00389 } 00390 } 00391 return StatusCode::SUCCESS; 00392 } 00393 00394 //------------------------------------------------------------------------------ 00395 StatusCode ServiceManager::startServices() 00396 //------------------------------------------------------------------------------ 00397 { 00398 StatusCode sc = StatusCode(StatusCode::FAILURE,true); 00399 MsgStream log(msgSvc(), "ServiceManager"); 00400 00401 // call initialize() for all services 00402 for (PListSvc::iterator it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00403 std::string name = (*it).first->name(); 00404 switch ((*it).first->FSMState()) { 00405 case Gaudi::StateMachine::RUNNING: 00406 log << MSG::DEBUG << "Service " << name 00407 << " already started" << endreq; 00408 break; 00409 case Gaudi::StateMachine::INITIALIZED: 00410 log << MSG::DEBUG << "Starting service " << name << endreq; 00411 sc = (*it).first->sysStart(); 00412 if( !sc.isSuccess() ) { 00413 log << MSG::ERROR << "Unable to start Service: " << (*it).first->name() << endreq; 00414 return sc; 00415 } break; 00416 default: 00417 log << MSG::ERROR << "Service " << name 00418 << " not in the correct state to be started (" 00419 << (*it).first->FSMState() << ")" << endreq; 00420 return StatusCode::FAILURE; 00421 } 00422 } 00423 return StatusCode::SUCCESS; 00424 } 00425 00426 00427 //------------------------------------------------------------------------------ 00428 StatusCode ServiceManager::stopServices() 00429 //------------------------------------------------------------------------------ 00430 { 00431 StatusCode sc; 00432 MsgStream log(msgSvc(), "ServiceManager"); 00433 00434 PListSvc::reverse_iterator it; 00435 // call stop() for all services 00436 for ( it = m_activesvc.rbegin(); it != m_activesvc.rend(); it++ ) { 00437 std::string name = (*it).first->name(); 00438 switch ((*it).first->FSMState()) { 00439 case Gaudi::StateMachine::INITIALIZED: 00440 log << MSG::DEBUG << "Service " << name 00441 << " already stopped" << endreq; 00442 break; 00443 case Gaudi::StateMachine::RUNNING: 00444 log << MSG::DEBUG << "Stopping service " << name << endreq; 00445 sc = (*it).first->sysStop(); 00446 if( !sc.isSuccess() ) { 00447 log << MSG::ERROR << "Unable to stop Service: " << (*it).first->name() << endreq; 00448 return sc; 00449 } break; 00450 default: 00451 log << MSG::ERROR << "Service " << name 00452 << " not in the correct state to be stopped (" 00453 << (*it).first->FSMState() << ")" << endreq; 00454 return StatusCode::FAILURE; 00455 } 00456 } 00457 return StatusCode::SUCCESS; 00458 } 00459 00460 //------------------------------------------------------------------------------ 00461 StatusCode ServiceManager::reinitializeServices() 00462 //------------------------------------------------------------------------------ 00463 { 00464 StatusCode sc; 00465 00466 PListSvc::iterator it; 00467 // Re-Initialize all services 00468 for ( it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00469 sc = (*it).first->sysReinitialize(); 00470 if( !sc.isSuccess() ) { 00471 MsgStream log(msgSvc(), "ServiceManager"); 00472 log << MSG::ERROR << "Unable to re-initialize Service: " << (*it).first->name() << endreq; 00473 return StatusCode::FAILURE; 00474 } 00475 } 00476 return StatusCode::SUCCESS; 00477 } 00478 00479 //------------------------------------------------------------------------------ 00480 StatusCode ServiceManager::restartServices() 00481 //------------------------------------------------------------------------------ 00482 { 00483 StatusCode sc; 00484 00485 PListSvc::iterator it; 00486 // Re-Start all services 00487 for ( it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00488 sc = (*it).first->sysRestart(); 00489 if( !sc.isSuccess() ) { 00490 MsgStream log(msgSvc(), "ServiceManager"); 00491 log << MSG::ERROR << "Unable to re-start Service: " << (*it).first->name() << endreq; 00492 return StatusCode::FAILURE; 00493 } 00494 } 00495 return StatusCode::SUCCESS; 00496 } 00497 00498 //------------------------------------------------------------------------------ 00499 StatusCode ServiceManager::finalizeServices() 00500 //------------------------------------------------------------------------------ 00501 { 00502 MsgStream log(msgSvc(), "ServiceManager"); 00503 00504 PListSvc::reverse_iterator its; 00505 00506 StatusCode sc(StatusCode::SUCCESS); 00507 00508 // make sure that HistogramDataSvc and THistSvc get finalized after the 00509 // ToolSvc, and StatusCodeSvc after that 00510 int pri_tool = getPriority("ToolSvc"); 00511 if (pri_tool != 0) { 00512 setPriority("THistSvc",pri_tool-1).ignore(); 00513 setPriority("ChronoStatSvc",pri_tool-2).ignore(); 00514 setPriority("AuditorSvc",pri_tool-3).ignore(); 00515 setPriority("HistogramDataSvc",pri_tool-1).ignore(); 00516 // Preserve the relative ordering between HistogramDataSvc and HistogramPersistencySvc 00517 setPriority("HistogramPersistencySvc",pri_tool-2).ignore(); 00518 } 00519 00520 // make sure the StatusCodeSvc gets finalized really late: 00521 setPriority("StatusCodeSvc",-9999).ignore(); 00522 00523 // call finalize() for all services in reverse order 00524 for ( its = m_activesvc.rbegin(); its != m_activesvc.rend(); its++ ) { 00525 // ignore the current state for the moment 00526 // if( Gaudi::StateMachine::INITIALIZED == (*it).first->state() ) { 00527 log << MSG::DEBUG << "Finalizing service " << (*its).first->name() << endreq; 00528 if ( !((*its).first->sysFinalize()).isSuccess() ) { 00529 log << MSG::WARNING << "Finalization of service " << (*its).first->name() 00530 << " failed" << endreq; 00531 sc = StatusCode::FAILURE; 00532 } 00533 } 00534 00535 // loop over all Active Services, removing them one by one. 00536 while (m_activesvc.size() != 0) { 00537 PListSvc::iterator its = m_activesvc.end(); 00538 its --; 00539 00541 // for ( its = m_activesvc.rbegin(); its != m_activesvc.rend(); its++ ) { 00542 // erase from m_listsvc before releasing 00543 for ( ListSvc::iterator ll = m_listsvc.begin(); ll != m_listsvc.end(); ++ll ) { 00544 if ( (*ll)->name() == its->first->name() ) { 00545 m_listsvc.erase( ll ); 00546 break; 00547 } 00548 } 00549 00550 // this may destroy the service 00551 (*its).first->release(); 00552 } 00553 00554 // clear the list of active services 00555 m_activesvc.erase(m_activesvc.begin(), m_activesvc.end() ); 00556 00557 return sc ; 00558 } 00559 00560 00561 //------------------------------------------------------------------------------ 00562 StatusCode ServiceManager::createService( const std::string& svctype, 00563 const std::string& svcname, 00564 IService*& service ) 00565 //------------------------------------------------------------------------------ 00566 { 00567 // Check is the service is already existing 00568 if( existsService( svcname ) ) { 00569 // return an error because a service with that name already exists 00570 return StatusCode::FAILURE; 00571 } 00572 00573 StatusCode rc = StatusCode::FAILURE; 00574 rc.setChecked(); //hack to avoid going into infinite recursion on ~StatusCode 00575 00576 MsgStream log(msgSvc(), "ServiceManager"); 00577 00578 service = PluginService::Create<IService*>(svctype, svcname, m_svclocator); 00579 if ( service ) { 00580 m_listsvc.push_back( service ); 00581 // Check the compatibility of the version of the interface obtained 00582 if( !isValidInterface(service) ) { 00583 log << MSG::FATAL << "Incompatible interface IService version for " << svctype << endreq; 00584 return StatusCode::FAILURE; 00585 } 00586 service->setServiceManager(this); 00587 return StatusCode(StatusCode::SUCCESS,true); 00588 } 00589 log << MSG::FATAL << "No Service factory for " << svctype << " available." << endreq; 00590 return StatusCode::FAILURE; 00591 } 00592 00594 StatusCode 00595 ServiceManager::getFactory(const std::string& svctype,const ISvcFactory*& factory) const 00596 { 00597 MapFactory::const_iterator itf = m_mapfactory.find( svctype ); 00598 factory = (itf == m_mapfactory.end()) ? 0 : (*itf).second; 00599 return (factory==0) ? StatusCode::FAILURE : StatusCode::SUCCESS; 00600 } 00601 00602 //------------------------------------------------------------------------------ 00603 IMessageSvc* ServiceManager::msgSvc() 00604 //------------------------------------------------------------------------------ 00605 { 00606 if( m_msgsvc == 0 ) { 00607 IService* iSvc(0); 00608 if ( (getService( "MessageSvc", iSvc, false)).isSuccess() ) 00609 m_msgsvc = dynamic_cast<IMessageSvc*>(iSvc); 00610 } 00611 return m_msgsvc; 00612 } 00613 00614 //------------------------------------------------------------------------------ 00615 int 00616 ServiceManager::getPriority(const std::string& name) const { 00617 //------------------------------------------------------------------------------ 00618 00619 PListSvc::const_iterator it; 00620 for (it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00621 if ((*it).first->name() == name) { 00622 return (*it).second; 00623 } 00624 } 00625 00626 return 0; 00627 00628 } 00629 00630 //------------------------------------------------------------------------------ 00631 StatusCode 00632 ServiceManager::setPriority(const std::string& name, int prio) { 00633 //------------------------------------------------------------------------------ 00634 00635 PListSvc::const_iterator it; 00636 for (it = m_activesvc.begin(); it != m_activesvc.end(); it++ ) { 00637 if ((*it).first->name() == name) { 00638 IService *svc = (*it).first; 00639 removeActiveService( svc ).ignore(); 00640 return addService(svc,prio); 00641 } 00642 } 00643 00644 return StatusCode::FAILURE; 00645 00646 }