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