| # Gaudi Framework, version v22r4 |

Home |  | Generated: Fri Sep 2 2011

# ServiceManager.cpp

Go to the documentation of this file.

    00001 // Include files
    00002 #include "ServiceManager.h"
    00003 #include "GaudiKernel/IService.h"
    00004 #include "GaudiKernel/SvcFactory.h"
    00005 #include "GaudiKernel/MsgStream.h"
    00006 #include "GaudiKernel/TypeNameString.h"
    00007 #include "GaudiKernel/System.h"
    00008 #include "GaudiKernel/Service.h"
    00009 #include "GaudiKernel/ObjectFactory.h"
    00010
    00011 #include <iostream>
    00012 #include <cassert>
    00013
    00014 #define ON_DEBUG if (msgLevel(MSG::DEBUG))
    00015 #define ON_VERBOSE if (msgLevel(MSG::VERBOSE))
    00016
    00017 #define DEBMSG ON_DEBUG debug()
    00018 #define VERMSG ON_VERBOSE verbose()
    00019
    00020 using ROOT::Reflex::PluginService;
    00021
    00023 static SmartIF<IService> no_service;
    00024
    00025 // constructor
    00026 ServiceManager::ServiceManager(IInterface* application):
    00027   base_class(application, IService::interfaceID()),
    00028   m_loopCheck(true),
    00029   m_appSvc(application)
    00030 {
    00031   // Set the service locator to myself
    00032   m_svcLocator = static_cast<ISvcLocator*>(this);
    00033
    00034   addRef(); // Initial count set to 1
    00035 }
    00036
    00037 // destructor
    00038 ServiceManager::~ServiceManager() {
    00039   //-- inform the orphan services that I am gone....
    00040   for (ListSvc::iterator it = m_listsvc.begin(); it != m_listsvc.end(); it++ ) {
    00041     it->service->setServiceManager(0);
    00042   }
    00043 }
    00044
    00045 //------------------------------------------------------------------------------
    00046 // Instantiate a service
    00047 SmartIF<IService>& ServiceManager::createService(const Gaudi::Utils::TypeNameString& typeName)
    00048 //------------------------------------------------------------------------------
    00049 {
    00050   // Check if the service is already existing
    00051   if(existsService(typeName.name())) {
    00052     // return an error because a service with that name already exists
    00053     return no_service;
    00054   }
    00055
    00057   StatusCode rc = StatusCode::FAILURE;
    00058   rc.setChecked(); //hack to avoid going into infinite recursion on ~StatusCode
    00059
    00060   const std::string &name = typeName.name();
    00061   std::string type = typeName.type();
    00062   if (!typeName.haveType()) { // the type is not explicit
    00063     // see we have some specific type mapping for the name
    00064     MapType::iterator it = m_maptype.find(typeName.name());
    00065     if( it != m_maptype.end() ) {
    00066       type = (*it).second; // use the declared type
    00067     }
    00068   }
    00069
    00071   std::string::size_type ip;
    00072   if ( (ip = type.find("__")) != std::string::npos) {
    00073     type.erase(ip,type.length());
    00074   }
    00075
    00076   IService* service = PluginService::Create<IService*>(type, name, static_cast<ISvcLocator*>(this)); // serviceLocator().get());
    00077   if ( !service ) {
    00078     service = PluginService::CreateWithId<IService*>(type, name, static_cast<ISvcLocator*>(this)); // serviceLocator().get());
    00079   }
    00080
    00081   if ( service ) {
    00082     m_listsvc.push_back(service);
    00083     // Check the compatibility of the version of the interface obtained
    00084     if( !isValidInterface(service) ) {
    00085       fatal() << "Incompatible interface IService version for " << type << endmsg;
    00086       return no_service;
    00087     }
    00088     service->setServiceManager(this);
    00089     return m_listsvc.back().service;
    00090   }
    00091   fatal() << "No Service factory for " << type << " available." << endmsg;
    00092   return no_service;
    00093 }
    00094
    00095 //------------------------------------------------------------------------------
    00096 // add a service to the managed list
    00097 StatusCode ServiceManager::addService(IService* svc, int prio)
    00098 //------------------------------------------------------------------------------
    00099 {
    00100   ListSvc::iterator it = find(svc);
    00101   if (it != m_listsvc.end()) {
    00102     it->priority = prio; // if the service is already known, it is equivalent to a setPriority
    00103     it->active = true;   // and make it active
    00104   } else {
    00105     m_listsvc.push_back(ServiceItem(svc,prio,true));
    00106   }
    00107   return StatusCode::SUCCESS;
    00108 }
    00109
    00110 //------------------------------------------------------------------------------
    00111 // add the service with the give type and name to the active list
    00112 StatusCode ServiceManager::addService(const Gaudi::Utils::TypeNameString& typeName, int prio)
    00113 //------------------------------------------------------------------------------
    00114 {
    00115   ListSvc::iterator it = find(typeName.name()); // try to find the service by name
    00116   if (it == m_listsvc.end()) { // not found
    00117     // If the service does not exist, we create it
    00118     SmartIF<IService> &svc = createService(typeName);
    00119     if (svc.isValid()) {
    00120       StatusCode sc = StatusCode(StatusCode::SUCCESS, true);
    00121       if (targetFSMState() >= Gaudi::StateMachine::INITIALIZED) {
    00122         sc = svc->sysInitialize();
    00123         if (sc.isSuccess() && targetFSMState() >= Gaudi::StateMachine::RUNNING) {
    00124           sc = svc->sysStart();
    00125         }
    00126       }
    00127       it = find(svc.get()); // now it is in the list because createService added it
    00128       if(sc.isFailure()) { // if initialization failed, remove it from the list
    00129         error() << "Unable to initialize service \"" << typeName.name() << "\""
    00130                 << endmsg;
    00131         m_listsvc.erase(it);
    00132         // Note: removing it from the list + the SmartIF going out of scope should trigger the delete
    00133         // delete svc.get();
    00134         return sc;
    00135       } else { // initialization successful, we can work with the service
    00136         // Move the just initialized service to the back of the list
    00137         // (we care more about order of initialization than of creation)
    00138         m_listsvc.push_back(*it);
    00139         m_listsvc.erase(it);
    00140         it = --m_listsvc.end(); // last entry (the iterator was invalidated by erase)
    00141       }
    00142     } else {
    00143       return StatusCode::FAILURE;
    00144     }
    00145   }
    00146   // 'it' is defined because either we found the service or we created it
    00147   // Now we can activate the service
    00148   it->priority = prio; // if the service is already known, it is equivalent to a setPriority
    00149   it->active = true;   // and make it active
    00150   return StatusCode(StatusCode::SUCCESS, true);
    00151 }
    00152
    00153 //------------------------------------------------------------------------------
    00154 // Returns a smart pointer to a service.
    00155 SmartIF<IService> &ServiceManager::service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf) {
    00156   const std::string &name = typeName.name();
    00157   ListSvc::iterator it = find(name);
    00158
    00159   if (it !=  m_listsvc.end()) {
    00160     if (m_loopCheck &&
    00161         (createIf && it->service->FSMState() == Gaudi::StateMachine::CONFIGURED)) {
    00162       error()
    00163           << "Initialization loop detected when creating service \"" << name
    00164           << "\""
    00165           << endmsg;
    00166       return no_service;
    00167     }
    00168     return it->service;
    00169   } else {
    00170     // Service not found. The user may be interested in one of the interfaces
    00171     // of the application manager itself
    00172     if( name == "ApplicationMgr" ||
    00173         name == "APPMGR" ||
    00174         name == "" ) {
    00175       return m_appSvc;
    00176     } else if ( createIf ){
    00177       //last resort: we try to create the service
    00178       if (addService(typeName).isSuccess()){
    00179         return find(name)->service;
    00180       }
    00181     }
    00182   }
    00183   return no_service;
    00184 }
    00185
    00186 //------------------------------------------------------------------------------
    00187 const std::list<IService*>& ServiceManager::getServices( ) const
    00188 //------------------------------------------------------------------------------
    00189 {
    00190   m_listOfPtrs.clear();
    00191   for (ListSvc::const_iterator it = m_listsvc.begin(); it != m_listsvc.end(); ++it) {
    00192     m_listOfPtrs.push_back(const_cast<IService*>(it->service.get()));
    00193   }
    00194   return m_listOfPtrs;
    00195 }
    00196
    00197 //------------------------------------------------------------------------------
    00198 bool ServiceManager::existsService( const std::string& name) const
    00199 //------------------------------------------------------------------------------
    00200 {
    00201   return find(name) != m_listsvc.end();
    00202 }
    00203
    00204 //------------------------------------------------------------------------------
    00205 StatusCode ServiceManager::removeService(IService* svc)
    00206 //------------------------------------------------------------------------------
    00207 {
    00208   ListSvc::iterator it = find(svc);
    00209   if (it != m_listsvc.end()) {
    00210     m_listsvc.erase(it);
    00211     return StatusCode(StatusCode::SUCCESS,true);
    00212   }
    00213   return StatusCode(StatusCode::FAILURE,true);
    00214 }
    00215
    00216 //------------------------------------------------------------------------------
    00217 StatusCode ServiceManager::removeService(const std::string& name)
    00218 //------------------------------------------------------------------------------
    00219 {
    00220   ListSvc::iterator it = find(name);
    00221   if (it != m_listsvc.end()) {
    00222     m_listsvc.erase(it);
    00223     return StatusCode::SUCCESS;
    00224   }
    00225   return StatusCode::FAILURE;
    00226 }
    00227
    00228 //------------------------------------------------------------------------------
    00229 StatusCode ServiceManager::declareSvcType( const std::string& svcname,
    00230                                            const std::string& svctype )
    00231 //------------------------------------------------------------------------------
    00232 {
    00233   std::pair<MapType::iterator, bool> p = m_maptype.insert(std::make_pair(svcname, svctype));
    00234   if( p.second == false) {
    00235     m_maptype.erase ( p.first );
    00236     p = m_maptype.insert(std::make_pair(svcname, svctype) );
    00237     if( p.second == false) return StatusCode::FAILURE;
    00238   }
    00239   return StatusCode::SUCCESS;
    00240 }
    00241
    00242 //------------------------------------------------------------------------------
    00243 StatusCode ServiceManager::initialize()
    00244 //------------------------------------------------------------------------------
    00245 {
    00246   m_listsvc.sort(); // ensure that the list is ordered by priority
    00247   // we work on a copy to avoid to operate twice on the services created on demand
    00248   // (which are already in the correct state.
    00249   ListSvc tmpList(m_listsvc);
    00250
    00251   StatusCode sc(StatusCode::SUCCESS, true);
    00252   // call initialize() for all services
    00253   for (ListSvc::iterator it = tmpList.begin(); it != tmpList.end(); ++it ) {
    00254     if (!it->active) continue; // only act on active services
    00255     const std::string& name = it->service->name();
    00256     switch (it->service->FSMState()) {
    00257     case Gaudi::StateMachine::INITIALIZED:
    00258       DEBMSG << "Service " << name << " already initialized" << endmsg;
    00259       break;
    00260     case Gaudi::StateMachine::OFFLINE:
    00261       DEBMSG << "Initializing service " << name << endmsg;
    00262       sc = it->service->sysInitialize();
    00263       if( !sc.isSuccess() ) {
    00264         error() << "Unable to initialize Service: " << name << endmsg;
    00265         return sc;
    00266       } break;
    00267     default:
    00268       error() << "Service " << name
    00269           << " not in the correct state to be initialized ("
    00270           << it->service->FSMState() << ")" << endmsg;
    00271       return StatusCode::FAILURE;
    00272     }
    00273   }
    00274   return StatusCode::SUCCESS;
    00275 }
    00276
    00277 //------------------------------------------------------------------------------
    00278 StatusCode ServiceManager::start()
    00279 //------------------------------------------------------------------------------
    00280 {
    00281   m_listsvc.sort(); // ensure that the list is ordered by priority
    00282   // we work on a copy to avoid to operate twice on the services created on demand
    00283   // (which are already in the correct state.
    00284   ListSvc tmpList(m_listsvc);
    00285
    00286   StatusCode sc(StatusCode::SUCCESS, true);
    00287   // call initialize() for all services
    00288   for (ListSvc::iterator it = tmpList.begin(); it != tmpList.end(); ++it ) {
    00289     if (!it->active) continue; // only act on active services
    00290     const std::string& name = it->service->name();
    00291     switch (it->service->FSMState()) {
    00292     case Gaudi::StateMachine::RUNNING:
    00293       DEBMSG << "Service " << name
    00294           << " already started" << endmsg;
    00295       break;
    00296     case Gaudi::StateMachine::INITIALIZED:
    00297       DEBMSG << "Starting service " << name << endmsg;
    00298       sc = it->service->sysStart();
    00299       if( !sc.isSuccess() ) {
    00300         error() << "Unable to start Service: " << name << endmsg;
    00301         return sc;
    00302       } break;
    00303     default:
    00304       error() << "Service " << name
    00305           << " not in the correct state to be started ("
    00306           << it->service->FSMState() << ")" << endmsg;
    00307       return StatusCode::FAILURE;
    00308     }
    00309   }
    00310   return StatusCode::SUCCESS;
    00311 }
    00312
    00313
    00314 //------------------------------------------------------------------------------
    00315 StatusCode ServiceManager::stop()
    00316 //------------------------------------------------------------------------------
    00317 {
    00318   m_listsvc.sort(); // ensure that the list is ordered by priority
    00319   // we work on a copy to avoid to operate twice on the services created on demand
    00320   // (which are already in the correct state.
    00321   ListSvc tmpList(m_listsvc);
    00322
    00323   StatusCode sc(StatusCode::SUCCESS, true);
    00324   ListSvc::reverse_iterator it;
    00325   // call stop() for all services
    00326   for (it = tmpList.rbegin(); it != tmpList.rend(); ++it ) {
    00327     if (!it->active) continue; // only act on active services
    00328     const std::string& name = it->service->name();
    00329     switch (it->service->FSMState()) {
    00330     case Gaudi::StateMachine::INITIALIZED:
    00331       DEBMSG << "Service " << name << " already stopped" << endmsg;
    00332       break;
    00333     case Gaudi::StateMachine::RUNNING:
    00334       DEBMSG << "Stopping service " << name << endmsg;
    00335       sc = it->service->sysStop();
    00336       if( !sc.isSuccess() ) {
    00337         error() << "Unable to stop Service: " << name << endmsg;
    00338         return sc;
    00339       } break;
    00340     default:
    00341       DEBMSG << "Service " << name
    00342           << " not in the correct state to be stopped ("
    00343           << it->service->FSMState() << ")" << endmsg;
    00344       return StatusCode::FAILURE;
    00345     }
    00346   }
    00347   return StatusCode::SUCCESS;
    00348 }
    00349
    00350 //------------------------------------------------------------------------------
    00351 StatusCode ServiceManager::reinitialize()
    00352 //------------------------------------------------------------------------------
    00353 {
    00354   m_listsvc.sort(); // ensure that the list is ordered by priority
    00355   // we work on a copy to avoid to operate twice on the services created on demand
    00356   // (which are already in the correct state.
    00357   ListSvc tmpList(m_listsvc);
    00358
    00359   StatusCode sc(StatusCode::SUCCESS, true);
    00360   ListSvc::iterator it;
    00361   // Re-Initialize all services
    00362   for ( it = tmpList.begin(); it != tmpList.end(); ++it ) {
    00363     if (!it->active) continue; // only act on active services
    00364     sc = it->service->sysReinitialize();
    00365     if( !sc.isSuccess() ) {
    00366       error() << "Unable to re-initialize Service: " << it->service->name() << endmsg;
    00367       return StatusCode::FAILURE;
    00368     }
    00369   }
    00370   return StatusCode::SUCCESS;
    00371 }
    00372
    00373 //------------------------------------------------------------------------------
    00374 StatusCode ServiceManager::restart()
    00375 //------------------------------------------------------------------------------
    00376 {
    00377   m_listsvc.sort(); // ensure that the list is ordered by priority
    00378   // we work on a copy to avoid to operate twice on the services created on demand
    00379   // (which are already in the correct state.
    00380   ListSvc tmpList(m_listsvc);
    00381
    00382   StatusCode sc(StatusCode::SUCCESS, true);
    00383   ListSvc::iterator it;
    00384   // Re-Start all services
    00385   for ( it = tmpList.begin(); it != tmpList.end(); ++it ) {
    00386     if (!it->active) continue; // only act on active services
    00387     sc = it->service->sysRestart();
    00388     if( !sc.isSuccess() ) {
    00389       error() << "Unable to re-start Service: " << it->service->name() << endmsg;
    00390       return StatusCode::FAILURE;
    00391     }
    00392   }
    00393   return StatusCode::SUCCESS;
    00394 }
    00395
    00396 //------------------------------------------------------------------------------
    00397 StatusCode ServiceManager::finalize()
    00398 //------------------------------------------------------------------------------
    00399 {
    00400   // make sure that HistogramDataSvc and THistSvc get finalized after the
    00401   // ToolSvc, and StatusCodeSvc after that
    00402   int pri_tool = getPriority("ToolSvc");
    00403   if (pri_tool != 0) {
    00404     setPriority("THistSvc",pri_tool-1).ignore();
    00405     setPriority("ChronoStatSvc",pri_tool-2).ignore();
    00406     setPriority("AuditorSvc",pri_tool-3).ignore();
    00407     setPriority("NTupleSvc",pri_tool-1).ignore();
    00408     setPriority("HistogramDataSvc",pri_tool-1).ignore();
    00409     // Preserve the relative ordering between HistogramDataSvc and HistogramPersistencySvc
    00410     setPriority("HistogramPersistencySvc",pri_tool-2).ignore();
    00411   }
    00412
    00413   // make sure the StatusCodeSvc gets finalized really late:
    00414   setPriority("StatusCodeSvc",-9999).ignore();
    00415
    00416   m_listsvc.sort(); // ensure that the list is ordered by priority
    00417   // we work on a copy to avoid to operate twice on the services created on demand
    00418   // (which are already in the correct state).
    00419   ListSvc tmpList(m_listsvc);
    00420
    00421   StatusCode sc(StatusCode::SUCCESS, true);
    00422   // call finalize() for all services in reverse order
    00423   ListSvc::reverse_iterator rit;
    00424   for (rit = tmpList.rbegin(); rit != tmpList.rend(); ++rit ) {
    00425     if (!rit->active) continue; // only act on active services
    00426     const std::string& name = rit->service->name();
    00427     // ignore the current state for the moment
    00428     // if( Gaudi::StateMachine::INITIALIZED == rit->service->state() ) {
    00429     DEBMSG << "Finalizing service " << name << endmsg;
    00430     if ( !(rit->service->sysFinalize()).isSuccess() ) {
    00431       warning() << "Finalization of service " << name << " failed" << endmsg;
    00432       sc = StatusCode::FAILURE;
    00433     }
    00434   }
    00435   DEBMSG << "Service reference count check:" << endmsg;
    00436   ListSvc::iterator it;
    00437   while (!tmpList.empty()) {
    00438     it = tmpList.begin();
    00439     const std::string& name = it->service->name();
    00440     const unsigned long rc = it->service->refCount() - 1; // exclude the count due to the temporary list
    00441     DEBMSG << "---- " << name
    00442            << " (refCount = " << rc << ")" << endmsg;
    00443     if (rc < 1) {
    00444       warning() << "Too low reference count for " << name
    00445                 << " (should not go below 1 at this point)" << endmsg;
    00446       it->service->addRef();
    00447     }
    00448     tmpList.pop_front();
    00449   }
    00450
    00451   // loop over all Active Services, removing them one by one.
    00452   // They should be deleted because the reference counting goes to 0.
    00453   it = m_listsvc.begin();
    00454   while (it != m_listsvc.end()) {
    00455     if (it->active) {
    00456       it = m_listsvc.erase(it);
    00457     } else {
    00458       ++it;
    00459     }
    00460   }
    00461   return sc ;
    00462 }
    00463
    00464
    00465 //------------------------------------------------------------------------------
    00466 int
    00467 ServiceManager::getPriority(const std::string& name) const {
    00468 //------------------------------------------------------------------------------
    00469   ListSvc::const_iterator it = find(name);
    00470   return (it != m_listsvc.end()) ? it->priority: 0;
    00471 }
    00472
    00473 //------------------------------------------------------------------------------
    00474 StatusCode
    00475 ServiceManager::setPriority(const std::string& name, int prio) {
    00476 //------------------------------------------------------------------------------
    00477   ListSvc::iterator it = find(name);
    00478   if (it != m_listsvc.end()) {
    00479     it->priority = prio;
    00480     return StatusCode::SUCCESS;
    00481   }
    00482   return StatusCode::FAILURE;
    00483 }
    00484
    00485 //------------------------------------------------------------------------------
    00486 // Get the value of the initialization loop check flag.
    00487 //------------------------------------------------------------------------------
    00488 bool ServiceManager::loopCheckEnabled() const {
    00489   return m_loopCheck;
    00490 }
    00491 //------------------------------------------------------------------------------
    00492 // Set the value of the initialization loop check flag.
    00493 //------------------------------------------------------------------------------
    00494 void ServiceManager::setLoopCheckEnabled(bool en) {
    00495   m_loopCheck = en;
    00496 }
    00497
    00498 DECLARE_OBJECT_FACTORY(ServiceManager)

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines