The Gaudi Framework  master (e68eea06)
Loading...
Searching...
No Matches
ServiceManager Class Reference

The ServiceManager class is in charge of the creation of concrete instances of Services. More...

#include </builds/gaudi/Gaudi/GaudiCoreSvc/src/ApplicationMgr/ServiceManager.h>

Inheritance diagram for ServiceManager:
Collaboration diagram for ServiceManager:

Classes

struct  ServiceItem
 

Public Types

typedef std::list< ServiceItemListSvc
 
typedef std::map< std::string, std::string, std::less<> > MapType
 
- Public Types inherited from extends< ComponentManager, ISvcManager, ISvcLocator >
using base_class
 Typedef to this class.
 
using extend_interfaces_base
 Typedef to the base of this class.
 
- Public Types inherited from CommonMessaging< implements< IComponentManager > >
using base_class
 
- Public Types inherited from extend_interfaces< Interfaces... >
using ext_iids
 take union of the ext_iids of all Interfaces...
 

Public Member Functions

 ServiceManager (IInterface *application)
 default creator
 
SmartIF< ISvcLocator > & serviceLocator () const override
 Function needed by CommonMessaging.
 
 ~ServiceManager () override
 virtual destructor
 
const std::list< IService * > & getServices () const override
 Return the list of Services.
 
bool existsService (std::string_view name) const override
 implementation of ISvcLocation::existsService
 
StatusCode addService (IService *svc, int prio=DEFAULT_SVC_PRIORITY) override
 implementation of ISvcManager::addService
 
StatusCode addService (const Gaudi::Utils::TypeNameString &typeName, int prio=DEFAULT_SVC_PRIORITY) override
 implementation of ISvcManager::addService
 
StatusCode removeService (IService *svc) override
 implementation of ISvcManager::removeService
 
StatusCode removeService (std::string_view name) override
 implementation of ISvcManager::removeService
 
StatusCode declareSvcType (std::string svcname, std::string svctype) override
 implementation of ISvcManager::declareSvcType
 
SmartIF< IService > & createService (const Gaudi::Utils::TypeNameString &nametype) override
 implementation of ISvcManager::createService NOTE: as this returns a &, we must guarantee that once created, these SmartIF remain pinned in their location, thus constraining the underlying implementation...
 
StatusCode initialize () override
 Initialization (from CONFIGURED to INITIALIZED).
 
StatusCode start () override
 Start (from INITIALIZED to RUNNING).
 
StatusCode stop () override
 Stop (from RUNNING to INITIALIZED).
 
StatusCode finalize () override
 Finalize (from INITIALIZED to CONFIGURED).
 
StatusCode reinitialize () override
 Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
 
StatusCode restart () override
 Initialization (from RUNNING to RUNNING, via INITIALIZED).
 
int getPriority (std::string_view name) const override
 manage priorities of services
 
StatusCode setPriority (std::string_view name, int pri) override
 
bool loopCheckEnabled () const override
 Get the value of the initialization loop check flag.
 
void setLoopCheckEnabled (bool en) override
 Set the value of the initialization loop check flag.
 
const std::string & name () const override
 Return the name of the manager (implementation of INamedInterface)
 
SmartIF< IService > & service (const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
 Returns a smart pointer to a service.
 
template<typename T>
SmartIF< T > service (const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)
 Returns a smart pointer to the requested interface of a service.
 
void outputLevelUpdate () override
 Function to call to update the outputLevel of the components (after a change in MessageSvc).
 
- Public Member Functions inherited from extends< ComponentManager, ISvcManager, ISvcLocator >
void const * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast.
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface.
 
std::vector< std::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames.
 
- Public Member Functions inherited from ComponentManager
 ComponentManager (IInterface *application, const InterfaceID &baseIID)
 Constructor.
 
const InterfaceIDcomponentBaseInterface () const override
 Basic interface id of the managed components.
 
void const * i_cast (const InterfaceID &iid) const override
 Specialized i_cast implementation.
 
SmartIF< ISvcLocator > & serviceLocator () const override
 
StatusCode configure () override
 Configuration (from OFFLINE to CONFIGURED).
 
StatusCode initialize () override
 Initialization (from CONFIGURED to INITIALIZED).
 
StatusCode start () override
 Start (from INITIALIZED to RUNNING).
 
StatusCode stop () override
 Stop (from RUNNING to INITIALIZED).
 
StatusCode finalize () override
 Finalize (from INITIALIZED to CONFIGURED).
 
StatusCode terminate () override
 Initialization (from CONFIGURED to OFFLINE).
 
StatusCode reinitialize () override
 Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
 
StatusCode restart () override
 Initialization (from RUNNING to RUNNING, via INITIALIZED).
 
Gaudi::StateMachine::State FSMState () const override
 Get the current state.
 
Gaudi::StateMachine::State targetFSMState () const override
 When we are in the middle of a transition, get the state where the transition is leading us.
 
- Public Member Functions inherited from CommonMessaging< implements< IComponentManager > >
MSG::Level msgLevel () const
 get the cached level (originally extracted from the embedded MsgStream)
 
bool msgLevel (MSG::Level lvl) const
 get the output level from the embedded MsgStream
 
- Public Member Functions inherited from CommonMessagingBase
virtual ~CommonMessagingBase ()=default
 Virtual destructor.
 
const SmartIF< IMessageSvc > & msgSvc () const
 The standard message service.
 
MsgStreammsgStream () const
 Return an uninitialized MsgStream.
 
MsgStreammsgStream (const MSG::Level level) const
 Predefined configurable message stream for the efficient printouts.
 
MsgStreamalways () const
 shortcut for the method msgStream(MSG::ALWAYS)
 
MsgStreamfatal () const
 shortcut for the method msgStream(MSG::FATAL)
 
MsgStreamerr () const
 shortcut for the method msgStream(MSG::ERROR)
 
MsgStreamerror () const
 shortcut for the method msgStream(MSG::ERROR)
 
MsgStreamwarning () const
 shortcut for the method msgStream(MSG::WARNING)
 
MsgStreaminfo () const
 shortcut for the method msgStream(MSG::INFO)
 
MsgStreamdebug () const
 shortcut for the method msgStream(MSG::DEBUG)
 
MsgStreamverbose () const
 shortcut for the method msgStream(MSG::VERBOSE)
 
MsgStreammsg () const
 shortcut for the method msgStream(MSG::INFO)
 

Private Member Functions

ListSvc::iterator find (std::string_view name)
 
ListSvc::const_iterator find (std::string_view name) const
 
ListSvc::iterator find (const IService *ptr)
 
ListSvc::const_iterator find (const IService *ptr) const
 
void dump () const
 

Private Attributes

ListSvc m_listsvc
 List of service maintained by ServiceManager This contains SmartIF<T> for all services – and because there can be SmartIF<T>& 'out there' that refer to these specific SmarIF<T>, we unfortunately must guarantee that they never move after creation.
 
MapType m_maptype
 Map of service name and service type.
 
bool m_loopCheck = true
 Check for service initialization loops.
 
SmartIF< IServicem_appSvc
 Pointer to the application IService interface.
 
std::list< IService * > m_listOfPtrs
 List of pointers to the know services used to implement getServices()
 
GaudiUtils::Map< InterfaceID, SmartIF< IInterface > > m_defaultImplementations
 
std::recursive_mutex m_gLock
 Mutex to synchronize shared service initialization between threads.
 
std::map< std::string, std::recursive_mutex > m_lockMap
 

Additional Inherited Members

- Protected Member Functions inherited from CommonMessaging< implements< IComponentManager > >
MSG::Level setUpMessaging () const
 Set up local caches.
 
MSG::Level resetMessaging ()
 Reinitialize internal states.
 
void updateMsgStreamOutputLevel (int level)
 Update the output level of the cached MsgStream.
 
- Protected Attributes inherited from ComponentManager
SmartIF< IInterfacem_application
 Pointer to the owner of the manager.
 
SmartIF< IStatefulm_stateful
 Pointer to the IStateful interface of the owner.
 
InterfaceID m_basicInterfaceId
 Basic interface id of the managed components.
 
SmartIF< ISvcLocatorm_svcLocator
 Service locator (needed to access the MessageSvc)
 
friend ApplicationMgr
 

Detailed Description

The ServiceManager class is in charge of the creation of concrete instances of Services.

The ApplicationMgr delegates the creation and bookkeeping of services to the ServiceManager. In order to be able to create services from which it is not know the concrete type it requires that the services has been declared in one of 3 possible ways: an abstract static creator function, a dynamic link library or an abstract factory reference.

Author
Pere Mato

Definition at line 40 of file ServiceManager.h.

Member Typedef Documentation

◆ ListSvc

Definition at line 53 of file ServiceManager.h.

◆ MapType

typedef std::map<std::string, std::string, std::less<> > ServiceManager::MapType

Definition at line 54 of file ServiceManager.h.

Constructor & Destructor Documentation

◆ ServiceManager()

ServiceManager::ServiceManager ( IInterface * application)

default creator

Definition at line 50 of file ServiceManager.cpp.

51 : base_class( application, IService::interfaceID() ), m_appSvc( application ) {
52 // Set the service locator to myself
53 m_svcLocator = this;
54 addRef(); // increase ref count, so we live forever...
55}
SmartIF< ISvcLocator > m_svcLocator
Service locator (needed to access the MessageSvc)
SmartIF< IService > m_appSvc
Pointer to the application IService interface.

◆ ~ServiceManager()

ServiceManager::~ServiceManager ( )
override

virtual destructor

Definition at line 57 of file ServiceManager.cpp.

57 {
58 //-- inform the orphan services that I am gone....
59 for ( auto& svc : m_listsvc ) svc.service->setServiceManager( nullptr );
60}
ListSvc m_listsvc
List of service maintained by ServiceManager This contains SmartIF<T> for all services – and because ...

Member Function Documentation

◆ addService() [1/2]

StatusCode ServiceManager::addService ( const Gaudi::Utils::TypeNameString & typeName,
int prio = DEFAULT_SVC_PRIORITY )
override

implementation of ISvcManager::addService

Definition at line 119 of file ServiceManager.cpp.

119 {
120 auto it = find( typeName.name() ); // try to find the service by name
121 if ( it == m_listsvc.end() ) { // not found
122 // If the service does not exist, we create it
123 SmartIF<IService>& svc =
124 createService( typeName ); // WARNING: svc is now a reference to something that lives in m_listsvc
125 if ( !svc ) return StatusCode::FAILURE;
126 it = find( svc.get() ); // now it is in the list because createService added it
127 it->priority = prio;
128 StatusCode sc = StatusCode::SUCCESS;
129 if ( targetFSMState() >= Gaudi::StateMachine::INITIALIZED ) { // WARNING: this can trigger a recursion!!!
130 sc = svc->sysInitialize();
131 if ( sc.isSuccess() && targetFSMState() >= Gaudi::StateMachine::RUNNING ) { sc = svc->sysStart(); }
132 }
133 if ( sc.isFailure() ) { // if initialization failed, remove it from the list
134 error() << "Unable to initialize service \"" << typeName.name() << "\"" << endmsg;
135 auto lck = std::scoped_lock{ m_gLock };
136 m_listsvc.erase( it );
137 // Note: removing it from the list + the SmartIF going out of scope should trigger the delete
138 // delete svc.get();
139 return sc;
140 }
141 // initialization successful, we can work with the service
142 // Move the just initialized service to the back of the list
143 // (we care more about order of initialization than of creation)
144 auto lck = std::scoped_lock{ m_gLock };
145 m_listsvc.push_back( *it );
146 m_listsvc.erase( it );
147 it = std::prev( std::end( m_listsvc ) ); // last entry (the iterator was invalidated by erase)
148 } else {
149 // if the service is already known, it is equivalent to a setPriority
150 it->priority = prio;
151 }
152 // 'it' is defined because either we found the service or we created it
153 // Now we can activate the service
154 it->active = true; // and make it active
155 return StatusCode::SUCCESS;
156}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Gaudi::StateMachine::State targetFSMState() const override
When we are in the middle of a transition, get the state where the transition is leading us.
SmartIF< IService > & createService(const Gaudi::Utils::TypeNameString &nametype) override
implementation of ISvcManager::createService NOTE: as this returns a &, we must guarantee that once c...
ListSvc::iterator find(std::string_view name)
std::recursive_mutex m_gLock
Mutex to synchronize shared service initialization between threads.
TYPE * get() const
Get interface pointer.
Definition SmartIF.h:82
bool isFailure() const
Definition StatusCode.h:129
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
std::string typeName(const std::type_info &typ)

◆ addService() [2/2]

StatusCode ServiceManager::addService ( IService * svc,
int prio = DEFAULT_SVC_PRIORITY )
override

implementation of ISvcManager::addService

Definition at line 107 of file ServiceManager.cpp.

107 {
108 auto it = find( svc );
109 auto lck = std::scoped_lock{ m_gLock };
110 if ( it != m_listsvc.end() ) {
111 it->priority = prio; // if the service is already known, it is equivalent to a setPriority
112 it->active = true; // and make it active
113 } else {
114 m_listsvc.emplace_back( svc, prio, true );
115 }
116 return StatusCode::SUCCESS;
117}

◆ createService()

SmartIF< IService > & ServiceManager::createService ( const Gaudi::Utils::TypeNameString & nametype)
override

implementation of ISvcManager::createService NOTE: as this returns a &, we must guarantee that once created, these SmartIF remain pinned in their location, thus constraining the underlying implementation...

Fix-Me
: what does this mean?

Definition at line 62 of file ServiceManager.cpp.

62 {
63 // Check if the service is already existing
64 if ( existsService( typeName.name() ) ) {
65 // return an error because a service with that name already exists
66 return no_service;
67 }
68
69 const std::string& name = typeName.name();
70 std::string type = typeName.type();
71 if ( !typeName.haveType() ) { // the type is not explicit
72 // see we have some specific type mapping for the name
73 auto it = m_maptype.find( typeName.name() );
74 if ( it != m_maptype.end() ) {
75 type = it->second; // use the declared type
76 }
77 }
78
80 auto ip = type.find( "__" );
81 if ( ip != std::string::npos ) type.erase( ip, type.length() );
82
83 IService* service = Service::Factory::create( type, name, this ).release();
84 if ( !service ) {
85 fatal() << "No Service factory for " << type << " available." << endmsg;
86 return no_service;
87 }
88 // FIXME: we used to have an invocation of isValidInterface, which implied an addRef() call
89 // now that isValidInterface has been deprecated, I added a call to addRef(), but I'm not
90 // sure if this is the right thing to do.
91 service->addRef();
92
93 if ( name == "JobOptionsSvc" ) {
94 if ( !dynamic_cast<Gaudi::Interfaces::IOptionsSvc*>( service ) ) {
95 fatal() << typeName << " does not implement Gaudi::Interfaces::IOptionsSvc" << endmsg;
96 return no_service;
97 }
98 }
99
100 auto lck = std::scoped_lock{ m_gLock };
101 m_listsvc.push_back( service );
102 service->setServiceManager( this );
103 return m_listsvc.back().service; // DANGER: returns a reference to a SmartIF in m_listsvc, and hence does no longer
104 // allow relocations of those...
105}
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
const std::string & name() const override
Return the name of the manager (implementation of INamedInterface)
bool existsService(std::string_view name) const override
implementation of ISvcLocation::existsService
SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true) override
Returns a smart pointer to a service.
MapType m_maptype
Map of service name and service type.

◆ declareSvcType()

StatusCode ServiceManager::declareSvcType ( std::string svcname,
std::string svctype )
override

implementation of ISvcManager::declareSvcType

Definition at line 224 of file ServiceManager.cpp.

224 {
225 m_maptype.insert_or_assign( std::move( svcname ), std::move( svctype ) );
226 return StatusCode::SUCCESS;
227}

◆ dump()

void ServiceManager::dump ( ) const
private

Definition at line 445 of file ServiceManager.cpp.

445 {
446
447 auto& log = info();
448 log << "\n"
449 << "===================== listing all services ===================\n"
450 << " prior ref name active\n";
451
452 for ( const auto& svc : m_listsvc ) {
453
454 log.width( 6 );
455 log.flags( std::ios_base::right );
456 log << svc.priority << " ";
457 log.width( 5 );
458 log << svc.service->refCount() << " ";
459 log.width( 30 );
460 log.flags( std::ios_base::left );
461 log << svc.service->name() << " ";
462 log.width( 2 );
463 log << svc.active << std::endl;
464 }
465
466 log << "=================================================================\n";
467 log << endmsg;
468}
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)

◆ existsService()

bool ServiceManager::existsService ( std::string_view name) const
override

implementation of ISvcLocation::existsService

Definition at line 208 of file ServiceManager.cpp.

208{ return find( name ) != m_listsvc.end(); }

◆ finalize()

StatusCode ServiceManager::finalize ( )
override

Finalize (from INITIALIZED to CONFIGURED).

Definition at line 357 of file ServiceManager.cpp.

357 {
358 // make sure that HistogramDataSvc and THistSvc get finalized after the
359 // ToolSvc, and the FileMgr after that
360 int pri_tool = getPriority( "ToolSvc" );
361 if ( pri_tool != 0 ) {
362 setPriority( "THistSvc", pri_tool - 10 ).ignore();
363 setPriority( "ChronoStatSvc", pri_tool - 20 ).ignore();
364 setPriority( "AuditorSvc", pri_tool - 30 ).ignore();
365 setPriority( "NTupleSvc", pri_tool - 10 ).ignore();
366 setPriority( "HistogramDataSvc", pri_tool - 10 ).ignore();
367 // Preserve the relative ordering between HistogramDataSvc and HistogramPersistencySvc
368 setPriority( "HistogramPersistencySvc", pri_tool - 20 ).ignore();
369 setPriority( "HistorySvc", pri_tool - 30 ).ignore();
370 setPriority( "FileMgr", pri_tool - 40 ).ignore();
371 }
372
373 // get list of PostFinalize clients
374 std::vector<IIncidentListener*> postFinList;
375 auto p_inc = service<IIncidentSvc>( "IncidentSvc", false );
376 if ( p_inc ) {
377 p_inc->getListeners( postFinList, IncidentType::SvcPostFinalize );
378 p_inc.reset();
379 }
380
381 // ensure that the list is ordered by priority
382 m_listsvc.sort();
383 // dump();
384
385 StatusCode sc = StatusCode::SUCCESS;
386 {
387 // we work on a copy to avoid to operate twice on the services created on demand
388 // which are already in the correct state.
389 // only act on active services
390 // call finalize() for all services in reverse order
391 for ( const auto& svc : reverse( activeSvc( m_listsvc ) ) ) {
392 const std::string& name = svc->name();
393 // ignore the current state for the moment
394 // if( Gaudi::StateMachine::INITIALIZED == svc->state() )
395 DEBMSG << "Finalizing service " << name << endmsg;
396 if ( !svc->sysFinalize().isSuccess() ) {
397 warning() << "Finalization of service " << name << " failed" << endmsg;
399 }
400 }
401 }
402
403 // call SvcPostFinalize on all clients
404 if ( !postFinList.empty() ) {
405 DEBMSG << "Will call SvcPostFinalize for " << postFinList.size() << " clients" << endmsg;
406 Incident inc( "ServiceManager", IncidentType::SvcPostFinalize );
407 for ( auto& itr : postFinList ) itr->handle( inc );
408 }
409
410 // loop over all Active Services, removing them one by one.
411 // They should be deleted because the reference counting goes to 0.
412 DEBMSG << "Looping over all active services..." << endmsg;
413 auto it = m_listsvc.begin();
414 while ( it != m_listsvc.end() ) {
415 DEBMSG << "---- " << it->service->name() << " (refCount = " << it->service->refCount() << ")" << endmsg;
416 if ( it->service->refCount() < 1 ) {
417 warning() << "Too low reference count for " << it->service->name() << " (should not go below 1 at this point)"
418 << endmsg;
419 it->service->addRef();
420 }
421 if ( it->active ) {
422 it = m_listsvc.erase( it );
423 } else {
424 ++it;
425 }
426 }
427 return sc;
428}
#define DEBMSG
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
int getPriority(std::string_view name) const override
manage priorities of services
StatusCode setPriority(std::string_view name, int pri) override
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition StatusCode.h:139
::details::reverse_wrapper< T > reverse(T &&iterable)
Definition reverse.h:58

◆ find() [1/4]

ListSvc::iterator ServiceManager::find ( const IService * ptr)
inlineprivate

Definition at line 140 of file ServiceManager.h.

140 {
141 auto lck = std::scoped_lock{ m_gLock };
142 return std::find( m_listsvc.begin(), m_listsvc.end(), ptr );
143 }

◆ find() [2/4]

ListSvc::const_iterator ServiceManager::find ( const IService * ptr) const
inlineprivate

Definition at line 144 of file ServiceManager.h.

144 {
145 auto lck = std::scoped_lock{ m_gLock };
146 return std::find( m_listsvc.begin(), m_listsvc.end(), ptr );
147 }

◆ find() [3/4]

ListSvc::iterator ServiceManager::find ( std::string_view name)
inlineprivate

Definition at line 132 of file ServiceManager.h.

132 {
133 auto lck = std::scoped_lock{ m_gLock };
134 return std::find( m_listsvc.begin(), m_listsvc.end(), name );
135 }

◆ find() [4/4]

ListSvc::const_iterator ServiceManager::find ( std::string_view name) const
inlineprivate

Definition at line 136 of file ServiceManager.h.

136 {
137 auto lck = std::scoped_lock{ m_gLock };
138 return std::find( m_listsvc.begin(), m_listsvc.end(), name );
139 }

◆ getPriority()

int ServiceManager::getPriority ( std::string_view name) const
override

manage priorities of services

Definition at line 430 of file ServiceManager.cpp.

430 {
431 auto it = find( name );
432 return ( it != m_listsvc.end() ) ? it->priority : 0;
433}

◆ getServices()

const std::list< IService * > & ServiceManager::getServices ( ) const
override

Return the list of Services.

Definition at line 201 of file ServiceManager.cpp.

201 {
202 m_listOfPtrs.clear();
203 std::transform( std::begin( m_listsvc ), std::end( m_listsvc ), std::back_inserter( m_listOfPtrs ),
204 []( ListSvc::const_reference i ) { return i.service.get(); } );
205 return m_listOfPtrs;
206}
std::list< IService * > m_listOfPtrs
List of pointers to the know services used to implement getServices()

◆ initialize()

StatusCode ServiceManager::initialize ( )
override

Initialization (from CONFIGURED to INITIALIZED).

Definition at line 229 of file ServiceManager.cpp.

229 {
230 // ensure that the list is ordered by priority
231 m_listsvc.sort();
232 // we work on a copy to avoid to operate twice on the services created on demand
233 // which are already in the correct state.
234
235 StatusCode sc = StatusCode::SUCCESS;
236 // call initialize() for all services
237 for ( auto& it : activeSvc( m_listsvc ) ) {
238 const std::string& name = it->name();
239 switch ( it->FSMState() ) {
241 DEBMSG << "Service " << name << " already initialized" << endmsg;
242 break;
244 DEBMSG << "Initializing service " << name << endmsg;
245 sc = it->sysInitialize();
246 if ( !sc.isSuccess() ) {
247 error() << "Unable to initialize Service: " << name << endmsg;
248 return sc;
249 }
250 break;
251 default:
252 error() << "Service " << name << " not in the correct state to be initialized (" << it->FSMState() << ")"
253 << endmsg;
254 return StatusCode::FAILURE;
255 }
256 }
257 return StatusCode::SUCCESS;
258}

◆ loopCheckEnabled()

bool ServiceManager::loopCheckEnabled ( ) const
override

Get the value of the initialization loop check flag.

Definition at line 442 of file ServiceManager.cpp.

442{ return m_loopCheck; }
bool m_loopCheck
Check for service initialization loops.

◆ name()

const std::string & ServiceManager::name ( ) const
inlineoverride

Return the name of the manager (implementation of INamedInterface)

Definition at line 114 of file ServiceManager.h.

114 {
115 static std::string _name = "ServiceManager";
116 return _name;
117 }

◆ outputLevelUpdate()

void ServiceManager::outputLevelUpdate ( )
override

Function to call to update the outputLevel of the components (after a change in MessageSvc).

Definition at line 470 of file ServiceManager.cpp.

470 {
472 for ( auto& svcItem : m_listsvc ) {
473 const auto svc = dynamic_cast<Service*>( svcItem.service.get() );
474 if ( svc ) svc->resetMessaging();
475 }
476}

◆ reinitialize()

StatusCode ServiceManager::reinitialize ( )
override

Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).

Definition at line 321 of file ServiceManager.cpp.

321 {
322 // ensure that the list is ordered by priority
323 m_listsvc.sort();
324 // we work on a copy to avoid to operate twice on the services created on demand
325 // which are already in the correct state.
326 // only act on active services
327 StatusCode sc = StatusCode::SUCCESS;
328 // Re-Initialize all services
329 for ( auto& svc : activeSvc( m_listsvc ) ) {
330 sc = svc->sysReinitialize();
331 if ( !sc.isSuccess() ) {
332 error() << "Unable to re-initialize Service: " << svc->name() << endmsg;
333 return StatusCode::FAILURE;
334 }
335 }
336 return StatusCode::SUCCESS;
337}

◆ removeService() [1/2]

StatusCode ServiceManager::removeService ( IService * svc)
override

implementation of ISvcManager::removeService

Definition at line 210 of file ServiceManager.cpp.

210 {
211 auto it = find( svc );
212 if ( it == m_listsvc.end() ) return StatusCode::FAILURE;
213 m_listsvc.erase( it );
214 return StatusCode::SUCCESS;
215}

◆ removeService() [2/2]

StatusCode ServiceManager::removeService ( std::string_view name)
override

implementation of ISvcManager::removeService

Definition at line 217 of file ServiceManager.cpp.

217 {
218 auto it = find( name );
219 if ( it == m_listsvc.end() ) return StatusCode::FAILURE;
220 m_listsvc.erase( it );
221 return StatusCode::SUCCESS;
222}

◆ restart()

StatusCode ServiceManager::restart ( )
override

Initialization (from RUNNING to RUNNING, via INITIALIZED).

Definition at line 339 of file ServiceManager.cpp.

339 {
340 // ensure that the list is ordered by priority
341 m_listsvc.sort();
342 // we work on a copy to avoid to operate twice on the services created on demand
343 // which are already in the correct state.
344 // only act on active services
345 StatusCode sc = StatusCode::SUCCESS;
346 // Re-Start all services
347 for ( auto& svc : activeSvc( m_listsvc ) ) {
348 sc = svc->sysRestart();
349 if ( !sc.isSuccess() ) {
350 error() << "Unable to re-start Service: " << svc->name() << endmsg;
351 return StatusCode::FAILURE;
352 }
353 }
354 return StatusCode::SUCCESS;
355}

◆ service() [1/2]

template<typename T>
SmartIF< T > ServiceManager::service ( const Gaudi::Utils::TypeNameString & typeName,
const bool createIf = true )
inline

Returns a smart pointer to the requested interface of a service.

Definition at line 124 of file ServiceManager.h.

124 {
125 return SmartIF<T>{ service( typeName, createIf ) };
126 }

◆ service() [2/2]

SmartIF< IService > & ServiceManager::service ( const Gaudi::Utils::TypeNameString & typeName,
const bool createIf = true )
override

Returns a smart pointer to a service.

Definition at line 158 of file ServiceManager.cpp.

158 {
159 const std::string& name = typeName.name();
160
161 // Acquire the RAII lock to avoid simultaneous attempts from different threads to initialize a service
162
163 auto* imut = [&] {
164 // get the global lock, then extract/create the service specific mutex
165 // then release global lock
166
167 auto lk = std::scoped_lock{ this->m_gLock };
168 auto mit = m_lockMap.find( name );
169 if ( mit == m_lockMap.end() ) {
170 mit = m_lockMap.emplace( std::piecewise_construct_t{}, std::forward_as_tuple( name ), std::forward_as_tuple() )
171 .first;
172 }
173 return &mit->second;
174 }();
175
176 {
177 // now we have the service specific lock on the above mutex
178 auto lk2 = std::scoped_lock{ *imut };
179
180 auto it = find( name );
181
182 if ( it != m_listsvc.end() ) {
183 if ( m_loopCheck && ( createIf && it->service->FSMState() == Gaudi::StateMachine::CONFIGURED ) ) {
184 error() << "Initialization loop detected when creating service \"" << name << "\"" << endmsg;
185 return no_service;
186 }
187 return it->service;
188 }
189
190 // Service not found. The user may be interested in one of the interfaces
191 // of the application manager itself
192 if ( name == "ApplicationMgr" || name == "APPMGR" || name == "" ) { return m_appSvc; }
193
194 // last resort: we try to create the service
195 if ( createIf && addService( typeName ).isSuccess() ) { return find( name )->service; }
196
197 return no_service;
198 }
199}
StatusCode addService(IService *svc, int prio=DEFAULT_SVC_PRIORITY) override
implementation of ISvcManager::addService
std::map< std::string, std::recursive_mutex > m_lockMap

◆ serviceLocator()

SmartIF< ISvcLocator > & ServiceManager::serviceLocator ( ) const
inlineoverride

Function needed by CommonMessaging.

Definition at line 60 of file ServiceManager.h.

60{ return m_svcLocator; }

◆ setLoopCheckEnabled()

void ServiceManager::setLoopCheckEnabled ( bool en)
override

Set the value of the initialization loop check flag.

Definition at line 443 of file ServiceManager.cpp.

443{ m_loopCheck = en; }

◆ setPriority()

StatusCode ServiceManager::setPriority ( std::string_view name,
int pri )
override

Definition at line 435 of file ServiceManager.cpp.

435 {
436 auto it = find( name );
437 if ( it == m_listsvc.end() ) return StatusCode::FAILURE;
438 it->priority = prio;
439 return StatusCode::SUCCESS;
440}

◆ start()

StatusCode ServiceManager::start ( )
override

Start (from INITIALIZED to RUNNING).

Definition at line 260 of file ServiceManager.cpp.

260 {
261 // ensure that the list is ordered by priority
262 m_listsvc.sort();
263 // we work on a copy to avoid to operate twice on the services created on demand
264 // (which are already in the correct state.
265 // only act on active services
266 StatusCode sc = StatusCode::SUCCESS;
267 // call initialize() for all services
268 for ( auto& it : activeSvc( m_listsvc ) ) {
269 const std::string& name = it->name();
270 switch ( it->FSMState() ) {
272 DEBMSG << "Service " << name << " already started" << endmsg;
273 break;
275 DEBMSG << "Starting service " << name << endmsg;
276 sc = it->sysStart();
277 if ( !sc.isSuccess() ) {
278 error() << "Unable to start Service: " << name << endmsg;
279 return sc;
280 }
281 break;
282 default:
283 error() << "Service " << name << " not in the correct state to be started (" << it->FSMState() << ")" << endmsg;
284 return StatusCode::FAILURE;
285 }
286 }
287 return StatusCode::SUCCESS;
288}

◆ stop()

StatusCode ServiceManager::stop ( )
override

Stop (from RUNNING to INITIALIZED).

Definition at line 290 of file ServiceManager.cpp.

290 {
291 // ensure that the list is ordered by priority
292 m_listsvc.sort();
293 // we work on a copy to avoid to operate twice on the services created on demand
294 // which are already in the correct state.
295 // only act on active services
296
297 StatusCode sc = StatusCode::SUCCESS;
298 // call stop() for all services
299 for ( const auto& svc : reverse( activeSvc( m_listsvc ) ) ) {
300 const std::string& name = svc->name();
301 switch ( svc->FSMState() ) {
303 DEBMSG << "Service " << name << " already stopped" << endmsg;
304 break;
306 DEBMSG << "Stopping service " << name << endmsg;
307 sc = svc->sysStop();
308 if ( !sc.isSuccess() ) {
309 error() << "Unable to stop Service: " << name << endmsg;
310 return sc;
311 }
312 break;
313 default:
314 DEBMSG << "Service " << name << " not in the correct state to be stopped (" << svc->FSMState() << ")" << endmsg;
315 return StatusCode::FAILURE;
316 }
317 }
318 return StatusCode::SUCCESS;
319}

Member Data Documentation

◆ m_appSvc

SmartIF<IService> ServiceManager::m_appSvc
private

Pointer to the application IService interface.

Definition at line 168 of file ServiceManager.h.

◆ m_defaultImplementations

GaudiUtils::Map<InterfaceID, SmartIF<IInterface> > ServiceManager::m_defaultImplementations
private

Definition at line 173 of file ServiceManager.h.

◆ m_gLock

std::recursive_mutex ServiceManager::m_gLock
mutableprivate

Mutex to synchronize shared service initialization between threads.

Definition at line 176 of file ServiceManager.h.

◆ m_listOfPtrs

std::list<IService*> ServiceManager::m_listOfPtrs
mutableprivate

List of pointers to the know services used to implement getServices()

Definition at line 171 of file ServiceManager.h.

◆ m_listsvc

ListSvc ServiceManager::m_listsvc
private

List of service maintained by ServiceManager This contains SmartIF<T> for all services – and because there can be SmartIF<T>& 'out there' that refer to these specific SmarIF<T>, we unfortunately must guarantee that they never move after creation.

Hence, we cannot use a plain std::vector here, as that may cause relocation and/or swapping of SmartIF<T>'s, and then the already handed out references may refer to the wrong item.... Note that we could use an std::vector<std::unique_ptr<ServiceItem>> (sometimes known as 'stable vector') as then the individual ServiceItems would stay pinned in their original location, but that would put ServiceItem on the heap... And maybe I'm way too paranoid...

Definition at line 150 of file ServiceManager.h.

◆ m_lockMap

std::map<std::string, std::recursive_mutex> ServiceManager::m_lockMap
mutableprivate

Definition at line 177 of file ServiceManager.h.

◆ m_loopCheck

bool ServiceManager::m_loopCheck = true
private

Check for service initialization loops.

Definition at line 165 of file ServiceManager.h.

◆ m_maptype

MapType ServiceManager::m_maptype
private

Map of service name and service type.

Definition at line 164 of file ServiceManager.h.


The documentation for this class was generated from the following files: