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 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
00171
00172 if( name == "ApplicationMgr" ||
00173 name == "APPMGR" ||
00174 name == "" ) {
00175 return m_appSvc;
00176 } else if ( createIf ){
00177
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();
00247
00248
00249 ListSvc tmpList(m_listsvc);
00250
00251 StatusCode sc(StatusCode::SUCCESS, true);
00252
00253 for (ListSvc::iterator it = tmpList.begin(); it != tmpList.end(); ++it ) {
00254 if (!it->active) continue;
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();
00282
00283
00284 ListSvc tmpList(m_listsvc);
00285
00286 StatusCode sc(StatusCode::SUCCESS, true);
00287
00288 for (ListSvc::iterator it = tmpList.begin(); it != tmpList.end(); ++it ) {
00289 if (!it->active) continue;
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();
00319
00320
00321 ListSvc tmpList(m_listsvc);
00322
00323 StatusCode sc(StatusCode::SUCCESS, true);
00324 ListSvc::reverse_iterator it;
00325
00326 for (it = tmpList.rbegin(); it != tmpList.rend(); ++it ) {
00327 if (!it->active) continue;
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();
00355
00356
00357 ListSvc tmpList(m_listsvc);
00358
00359 StatusCode sc(StatusCode::SUCCESS, true);
00360 ListSvc::iterator it;
00361
00362 for ( it = tmpList.begin(); it != tmpList.end(); ++it ) {
00363 if (!it->active) continue;
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();
00378
00379
00380 ListSvc tmpList(m_listsvc);
00381
00382 StatusCode sc(StatusCode::SUCCESS, true);
00383 ListSvc::iterator it;
00384
00385 for ( it = tmpList.begin(); it != tmpList.end(); ++it ) {
00386 if (!it->active) continue;
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
00401
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
00410 setPriority("HistogramPersistencySvc",pri_tool-2).ignore();
00411 }
00412
00413
00414 setPriority("StatusCodeSvc",-9999).ignore();
00415
00416 m_listsvc.sort();
00417
00418
00419 ListSvc tmpList(m_listsvc);
00420
00421 StatusCode sc(StatusCode::SUCCESS, true);
00422
00423 ListSvc::reverse_iterator rit;
00424 for (rit = tmpList.rbegin(); rit != tmpList.rend(); ++rit ) {
00425 if (!rit->active) continue;
00426 const std::string& name = rit->service->name();
00427
00428
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;
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
00452
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
00487
00488 bool ServiceManager::loopCheckEnabled() const {
00489 return m_loopCheck;
00490 }
00491
00492
00493
00494 void ServiceManager::setLoopCheckEnabled(bool en) {
00495 m_loopCheck = en;
00496 }
00497
00498 DECLARE_OBJECT_FACTORY(ServiceManager)