Go to the documentation of this file.00001
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
00026 ServiceManager::ServiceManager(IInterface* application):
00027 base_class(application, IService::interfaceID()),
00028 m_loopCheck(true),
00029 m_appSvc(application)
00030 {
00031
00032 m_svcLocator = static_cast<ISvcLocator*>(this);
00033
00034 addRef();
00035 }
00036
00037
00038 ServiceManager::~ServiceManager() {
00039
00040 for (ListSvc::iterator it = m_listsvc.begin(); it != m_listsvc.end(); it++ ) {
00041 it->service->setServiceManager(0);
00042 }
00043 }
00044
00045
00046
00047 SmartIF<IService>& ServiceManager::createService(const Gaudi::Utils::TypeNameString& typeName)
00048
00049 {
00050
00051 if(existsService(typeName.name())) {
00052
00053 return no_service;
00054 }
00055
00057 StatusCode rc = StatusCode::FAILURE;
00058 rc.setChecked();
00059
00060 const std::string &name = typeName.name();
00061 std::string type = typeName.type();
00062 if (!typeName.haveType()) {
00063
00064 MapType::iterator it = m_maptype.find(typeName.name());
00065 if( it != m_maptype.end() ) {
00066 type = (*it).second;
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));
00077 if ( !service ) {
00078 service = PluginService::CreateWithId<IService*>(type, name, static_cast<ISvcLocator*>(this));
00079 }
00080
00081 if ( service ) {
00082 m_listsvc.push_back(service);
00083
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
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;
00103 it->active = true;
00104 } else {
00105 m_listsvc.push_back(ServiceItem(svc,prio,true));
00106 }
00107 return StatusCode::SUCCESS;
00108 }
00109
00110
00111
00112 StatusCode ServiceManager::addService(const Gaudi::Utils::TypeNameString& typeName, int prio)
00113
00114 {
00115 ListSvc::iterator it = find(typeName.name());
00116 if (it == m_listsvc.end()) {
00117
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());
00128 if(sc.isFailure()) {
00129 error() << "Unable to initialize service \"" << typeName.name() << "\""
00130 << endmsg;
00131 m_listsvc.erase(it);
00132
00133
00134 return sc;
00135 } else {
00136
00137
00138 m_listsvc.push_back(*it);
00139 m_listsvc.erase(it);
00140 it = --m_listsvc.end();
00141 }
00142 } else {
00143 return StatusCode::FAILURE;
00144 }
00145 }
00146
00147
00148 it->priority = prio;
00149 it->active = true;
00150 return StatusCode(StatusCode::SUCCESS, true);
00151 }
00152
00153
00154
00155 SmartIF<IService> &ServiceManager::service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf) {
00156 const std::string &name = typeName.name();
00157
00158
00159 boost::lock_guard<boost::recursive_mutex> lck(m_svcinitmutex);
00160
00161 ListSvc::iterator it = find(name);
00162
00163 if (it != m_listsvc.end()) {
00164 if (m_loopCheck &&
00165 (createIf && it->service->FSMState() == Gaudi::StateMachine::CONFIGURED)) {
00166 error()
00167 << "Initialization loop detected when creating service \"" << name
00168 << "\""
00169 << endmsg;
00170 return no_service;
00171 }
00172 return it->service;
00173 } else {
00174
00175
00176 if( name == "ApplicationMgr" ||
00177 name == "APPMGR" ||
00178 name == "" ) {
00179 return m_appSvc;
00180 } else if ( createIf ){
00181
00182 if (addService(typeName).isSuccess()){
00183 return find(name)->service;
00184 }
00185 }
00186 }
00187 return no_service;
00188 }
00189
00190
00191 const std::list<IService*>& ServiceManager::getServices( ) const
00192
00193 {
00194 m_listOfPtrs.clear();
00195 for (ListSvc::const_iterator it = m_listsvc.begin(); it != m_listsvc.end(); ++it) {
00196 m_listOfPtrs.push_back(const_cast<IService*>(it->service.get()));
00197 }
00198 return m_listOfPtrs;
00199 }
00200
00201
00202 bool ServiceManager::existsService( const std::string& name) const
00203
00204 {
00205 return find(name) != m_listsvc.end();
00206 }
00207
00208
00209 StatusCode ServiceManager::removeService(IService* svc)
00210
00211 {
00212 ListSvc::iterator it = find(svc);
00213 if (it != m_listsvc.end()) {
00214 m_listsvc.erase(it);
00215 return StatusCode(StatusCode::SUCCESS,true);
00216 }
00217 return StatusCode(StatusCode::FAILURE,true);
00218 }
00219
00220
00221 StatusCode ServiceManager::removeService(const std::string& name)
00222
00223 {
00224 ListSvc::iterator it = find(name);
00225 if (it != m_listsvc.end()) {
00226 m_listsvc.erase(it);
00227 return StatusCode::SUCCESS;
00228 }
00229 return StatusCode::FAILURE;
00230 }
00231
00232
00233 StatusCode ServiceManager::declareSvcType( const std::string& svcname,
00234 const std::string& svctype )
00235
00236 {
00237 std::pair<MapType::iterator, bool> p = m_maptype.insert(std::make_pair(svcname, svctype));
00238 if( p.second == false) {
00239 m_maptype.erase ( p.first );
00240 p = m_maptype.insert(std::make_pair(svcname, svctype) );
00241 if( p.second == false) return StatusCode::FAILURE;
00242 }
00243 return StatusCode::SUCCESS;
00244 }
00245
00246
00247 StatusCode ServiceManager::initialize()
00248
00249 {
00250 m_listsvc.sort();
00251
00252
00253 ListSvc tmpList(m_listsvc);
00254
00255 StatusCode sc(StatusCode::SUCCESS, true);
00256
00257 for (ListSvc::iterator it = tmpList.begin(); it != tmpList.end(); ++it ) {
00258 if (!it->active) continue;
00259 const std::string& name = it->service->name();
00260 switch (it->service->FSMState()) {
00261 case Gaudi::StateMachine::INITIALIZED:
00262 DEBMSG << "Service " << name << " already initialized" << endmsg;
00263 break;
00264 case Gaudi::StateMachine::OFFLINE:
00265 DEBMSG << "Initializing service " << name << endmsg;
00266 sc = it->service->sysInitialize();
00267 if( !sc.isSuccess() ) {
00268 error() << "Unable to initialize Service: " << name << endmsg;
00269 return sc;
00270 } break;
00271 default:
00272 error() << "Service " << name
00273 << " not in the correct state to be initialized ("
00274 << it->service->FSMState() << ")" << endmsg;
00275 return StatusCode::FAILURE;
00276 }
00277 }
00278 return StatusCode::SUCCESS;
00279 }
00280
00281
00282 StatusCode ServiceManager::start()
00283
00284 {
00285 m_listsvc.sort();
00286
00287
00288 ListSvc tmpList(m_listsvc);
00289
00290 StatusCode sc(StatusCode::SUCCESS, true);
00291
00292 for (ListSvc::iterator it = tmpList.begin(); it != tmpList.end(); ++it ) {
00293 if (!it->active) continue;
00294 const std::string& name = it->service->name();
00295 switch (it->service->FSMState()) {
00296 case Gaudi::StateMachine::RUNNING:
00297 DEBMSG << "Service " << name
00298 << " already started" << endmsg;
00299 break;
00300 case Gaudi::StateMachine::INITIALIZED:
00301 DEBMSG << "Starting service " << name << endmsg;
00302 sc = it->service->sysStart();
00303 if( !sc.isSuccess() ) {
00304 error() << "Unable to start Service: " << name << endmsg;
00305 return sc;
00306 } break;
00307 default:
00308 error() << "Service " << name
00309 << " not in the correct state to be started ("
00310 << it->service->FSMState() << ")" << endmsg;
00311 return StatusCode::FAILURE;
00312 }
00313 }
00314 return StatusCode::SUCCESS;
00315 }
00316
00317
00318
00319 StatusCode ServiceManager::stop()
00320
00321 {
00322 m_listsvc.sort();
00323
00324
00325 ListSvc tmpList(m_listsvc);
00326
00327 StatusCode sc(StatusCode::SUCCESS, true);
00328 ListSvc::reverse_iterator it;
00329
00330 for (it = tmpList.rbegin(); it != tmpList.rend(); ++it ) {
00331 if (!it->active) continue;
00332 const std::string& name = it->service->name();
00333 switch (it->service->FSMState()) {
00334 case Gaudi::StateMachine::INITIALIZED:
00335 DEBMSG << "Service " << name << " already stopped" << endmsg;
00336 break;
00337 case Gaudi::StateMachine::RUNNING:
00338 DEBMSG << "Stopping service " << name << endmsg;
00339 sc = it->service->sysStop();
00340 if( !sc.isSuccess() ) {
00341 error() << "Unable to stop Service: " << name << endmsg;
00342 return sc;
00343 } break;
00344 default:
00345 DEBMSG << "Service " << name
00346 << " not in the correct state to be stopped ("
00347 << it->service->FSMState() << ")" << endmsg;
00348 return StatusCode::FAILURE;
00349 }
00350 }
00351 return StatusCode::SUCCESS;
00352 }
00353
00354
00355 StatusCode ServiceManager::reinitialize()
00356
00357 {
00358 m_listsvc.sort();
00359
00360
00361 ListSvc tmpList(m_listsvc);
00362
00363 StatusCode sc(StatusCode::SUCCESS, true);
00364 ListSvc::iterator it;
00365
00366 for ( it = tmpList.begin(); it != tmpList.end(); ++it ) {
00367 if (!it->active) continue;
00368 sc = it->service->sysReinitialize();
00369 if( !sc.isSuccess() ) {
00370 error() << "Unable to re-initialize Service: " << it->service->name() << endmsg;
00371 return StatusCode::FAILURE;
00372 }
00373 }
00374 return StatusCode::SUCCESS;
00375 }
00376
00377
00378 StatusCode ServiceManager::restart()
00379
00380 {
00381 m_listsvc.sort();
00382
00383
00384 ListSvc tmpList(m_listsvc);
00385
00386 StatusCode sc(StatusCode::SUCCESS, true);
00387 ListSvc::iterator it;
00388
00389 for ( it = tmpList.begin(); it != tmpList.end(); ++it ) {
00390 if (!it->active) continue;
00391 sc = it->service->sysRestart();
00392 if( !sc.isSuccess() ) {
00393 error() << "Unable to re-start Service: " << it->service->name() << endmsg;
00394 return StatusCode::FAILURE;
00395 }
00396 }
00397 return StatusCode::SUCCESS;
00398 }
00399
00400
00401 StatusCode ServiceManager::finalize()
00402
00403 {
00404
00405
00406 int pri_tool = getPriority("ToolSvc");
00407 if (pri_tool != 0) {
00408 setPriority("THistSvc",pri_tool-1).ignore();
00409 setPriority("ChronoStatSvc",pri_tool-2).ignore();
00410 setPriority("AuditorSvc",pri_tool-3).ignore();
00411 setPriority("NTupleSvc",pri_tool-1).ignore();
00412 setPriority("HistogramDataSvc",pri_tool-1).ignore();
00413
00414 setPriority("HistogramPersistencySvc",pri_tool-2).ignore();
00415 }
00416
00417
00418 setPriority("StatusCodeSvc",-9999).ignore();
00419
00420 m_listsvc.sort();
00421
00422
00423 ListSvc tmpList(m_listsvc);
00424
00425 StatusCode sc(StatusCode::SUCCESS, true);
00426
00427 ListSvc::reverse_iterator rit;
00428 for (rit = tmpList.rbegin(); rit != tmpList.rend(); ++rit ) {
00429 if (!rit->active) continue;
00430 const std::string& name = rit->service->name();
00431
00432
00433 DEBMSG << "Finalizing service " << name << endmsg;
00434 if ( !(rit->service->sysFinalize()).isSuccess() ) {
00435 warning() << "Finalization of service " << name << " failed" << endmsg;
00436 sc = StatusCode::FAILURE;
00437 }
00438 }
00439 DEBMSG << "Service reference count check:" << endmsg;
00440 ListSvc::iterator it;
00441 while (!tmpList.empty()) {
00442 it = tmpList.begin();
00443 const std::string& name = it->service->name();
00444 const unsigned long rc = it->service->refCount() - 1;
00445 DEBMSG << "---- " << name
00446 << " (refCount = " << rc << ")" << endmsg;
00447 if (rc < 1) {
00448 warning() << "Too low reference count for " << name
00449 << " (should not go below 1 at this point)" << endmsg;
00450 it->service->addRef();
00451 }
00452 tmpList.pop_front();
00453 }
00454
00455
00456
00457 it = m_listsvc.begin();
00458 while (it != m_listsvc.end()) {
00459 if (it->active) {
00460 it = m_listsvc.erase(it);
00461 } else {
00462 ++it;
00463 }
00464 }
00465 return sc ;
00466 }
00467
00468
00469
00470 int
00471 ServiceManager::getPriority(const std::string& name) const {
00472
00473 ListSvc::const_iterator it = find(name);
00474 return (it != m_listsvc.end()) ? it->priority: 0;
00475 }
00476
00477
00478 StatusCode
00479 ServiceManager::setPriority(const std::string& name, int prio) {
00480
00481 ListSvc::iterator it = find(name);
00482 if (it != m_listsvc.end()) {
00483 it->priority = prio;
00484 return StatusCode::SUCCESS;
00485 }
00486 return StatusCode::FAILURE;
00487 }
00488
00489
00490
00491
00492 bool ServiceManager::loopCheckEnabled() const {
00493 return m_loopCheck;
00494 }
00495
00496
00497
00498 void ServiceManager::setLoopCheckEnabled(bool en) {
00499 m_loopCheck = en;
00500 }
00501
00502 DECLARE_OBJECT_FACTORY(ServiceManager)