Gaudi Framework, version v20r2

Generated: 18 Jul 2008

ServiceManager.cpp

Go to the documentation of this file.
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 } 

Generated at Fri Jul 18 11:59:23 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004