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