The Gaudi Framework  v36r9 (fd2bdac3)
ToolSvc Class Reference

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

Inheritance diagram for ToolSvc:
Collaboration diagram for ToolSvc:

Public Member Functions

 ~ToolSvc () override
 Destructor. More...
 
StatusCode finalize () override
 Finalize the service. More...
 
StatusCode start () override
 
StatusCode stop () override
 
StatusCode retrieve (std::string_view type, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent, bool createIf) override
 Retrieve tool, create it by default as common tool if it does not already exist. More...
 
StatusCode retrieve (std::string_view tooltype, std::string_view toolname, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent, bool createIf) override
 Retrieve tool, create it by default as common tool if it does not already exist. More...
 
std::vector< std::stringgetInstances (std::string_view toolType) override
 Get names of all tool instances of a given type. More...
 
std::vector< std::stringgetInstances () const override
 Get names of all tool instances. More...
 
std::vector< IAlgTool * > getTools () const override
 Get pointers to all tool instances. More...
 
StatusCode releaseTool (IAlgTool *tool) override
 Release tool. More...
 
StatusCode create (const std::string &type, const IInterface *parent, IAlgTool *&tool)
 Create Tool standard way with automatically assigned name. More...
 
StatusCode create (const std::string &type, const std::string &name, const IInterface *parent, IAlgTool *&tool)
 Create Tool standard way with specified name. More...
 
bool existsTool (std::string_view toolname) const
 Check if the tool instance exists. More...
 
std::string nameTool (std::string_view nameByUser, const IInterface *parent)
 Get Tool full name by combining nameByUser and "parent" part. More...
 
void registerObserver (IToolSvc::Observer *obs) override
 
- Public Member Functions inherited from extends< Service, IToolSvc >
void * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast. More...
 
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface. More...
 
std::vector< std::stringgetInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames. More...
 
- Public Member Functions inherited from Service
const std::stringname () const override
 Retrieve name of the service
More...
 
StatusCode configure () override
 
StatusCode initialize () override
 
StatusCode start () override
 
StatusCode stop () override
 
StatusCode finalize () override
 
StatusCode terminate () override
 
Gaudi::StateMachine::State FSMState () const override
 
Gaudi::StateMachine::State targetFSMState () const override
 
StatusCode reinitialize () override
 
StatusCode restart () override
 
StatusCode sysInitialize () override
 Initialize Service
More...
 
StatusCode sysStart () override
 Initialize Service
More...
 
StatusCode sysStop () override
 Initialize Service
More...
 
StatusCode sysFinalize () override
 Finalize Service
More...
 
StatusCode sysReinitialize () override
 Re-initialize the Service. More...
 
StatusCode sysRestart () override
 Re-initialize the Service. More...
 
 Service (std::string name, ISvcLocator *svcloc)
 Standard Constructor
More...
 
SmartIF< ISvcLocator > & serviceLocator () const override
 Retrieve pointer to service locator
More...
 
template<class T >
StatusCode service (const std::string &name, const T *&psvc, bool createIf=true) const
 Access a service by name, creating it if it doesn't already exist. More...
 
template<class T >
StatusCode service (const std::string &name, T *&psvc, bool createIf=true) const
 
template<typename IFace = IService>
SmartIF< IFace > service (const std::string &name, bool createIf=true) const
 
template<class T >
StatusCode service (const std::string &svcType, const std::string &svcName, T *&psvc) const
 Access a service by name and type, creating it if it doesn't already exist. More...
 
template<class T >
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, ToolHandle< T > &hndl, const std::string &doc="none")
 
template<class T >
StatusCode declareTool (ToolHandle< T > &handle, bool createIf=true)
 
template<class T >
StatusCode declareTool (ToolHandle< T > &handle, std::string toolTypeAndName, bool createIf=true)
 Declare used tool. More...
 
template<class T >
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, ToolHandleArray< T > &hndlArr, const std::string &doc="none")
 
template<class T >
void addToolsArray (ToolHandleArray< T > &hndlArr)
 
const std::vector< IAlgTool * > & tools () const
 
SmartIF< IAuditorSvc > & auditorSvc () const
 The standard auditor service.May not be invoked before sysInitialize() has been invoked. More...
 
- Public Member Functions inherited from PropertyHolder< CommonMessaging< implements< IService, IProperty, IStateful > > >
 PropertyHolder ()=default
 
Gaudi::Details::PropertyBasedeclareProperty (Gaudi::Details::PropertyBase &prop)
 Declare a property. More...
 
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, TYPE &value, const std::string &doc="none")
 Helper to wrap a regular data member and use it as a regular property. More...
 
Gaudi::Details::PropertyBasedeclareProperty (const std::string &name, Gaudi::Property< TYPE, VERIFIER, HANDLERS > &prop, const std::string &doc="none")
 Declare a PropertyBase instance setting name and documentation. More...
 
Gaudi::Details::PropertyBasedeclareRemoteProperty (const std::string &name, IProperty *rsvc, const std::string &rname="")
 Declare a remote property. More...
 
StatusCode setProperty (const std::string &name, const Gaudi::Details::PropertyBase &p) override
 set the property from another property with a different name More...
 
StatusCode setProperty (const std::string &s) override
 set the property from the formatted string More...
 
StatusCode setProperty (const Gaudi::Details::PropertyBase &p)
 Set the property from a property. More...
 
virtual StatusCode setProperty (const std::string &name, const Gaudi::Details::PropertyBase &p)=0
 Set the property from a property with a different name. More...
 
virtual StatusCode setProperty (const std::string &s)=0
 Set the property by string. More...
 
StatusCode setProperty (const std::string &name, const char *v)
 Special case for string literals. More...
 
StatusCode setProperty (const std::string &name, const std::string &v)
 Special case for std::string. More...
 
StatusCode setProperty (const std::string &name, const TYPE &value)
 set the property form the value More...
 
StatusCode setPropertyRepr (const std::string &n, const std::string &r) override
 set the property from name and value string representation More...
 
StatusCode getProperty (Gaudi::Details::PropertyBase *p) const override
 get the property More...
 
const Gaudi::Details::PropertyBasegetProperty (std::string_view name) const override
 get the property by name More...
 
StatusCode getProperty (std::string_view n, std::string &v) const override
 convert the property to the string More...
 
const std::vector< Gaudi::Details::PropertyBase * > & getProperties () const override
 get all properties More...
 
bool hasProperty (std::string_view name) const override
 Return true if we have a property with the given name. More...
 
Gaudi::Details::PropertyBaseproperty (std::string_view name) const
 \fixme property and bindPropertiesTo should be protected More...
 
void bindPropertiesTo (Gaudi::Interfaces::IOptionsSvc &optsSvc)
 
 PropertyHolder (const PropertyHolder &)=delete
 
PropertyHolderoperator= (const PropertyHolder &)=delete
 
- Public Member Functions inherited from CommonMessaging< implements< IService, IProperty, IStateful > >
MSG::Level msgLevel () const
 get the cached level (originally extracted from the embedded MsgStream) More...
 
bool msgLevel (MSG::Level lvl) const
 get the output level from the embedded MsgStream More...
 

Private Types

typedef std::recursive_mutex CallMutex
 

Private Member Functions

unsigned long totalToolRefCount () const
 The total number of refCounts on all tools in the instancesTools list. More...
 
unsigned long minimumToolRefCount () const
 The minimum number of refCounts of all tools. More...
 
StatusCode finalizeTool (IAlgTool *itool) const
 Finalize the given tool, with exception handling. More...
 

Private Attributes

std::vector< IAlgTool * > m_instancesTools
 Common Tools. More...
 
IHistorySvcm_pHistorySvc = nullptr
 Pointer to HistorySvc. More...
 
std::vector< IToolSvc::Observer * > m_observers
 
CallMutex m_mut
 

Additional Inherited Members

- Public Types inherited from extends< Service, IToolSvc >
using base_class = extends
 Typedef to this class. More...
 
using extend_interfaces_base = extend_interfaces< Interfaces... >
 Typedef to the base of this class. More...
 
- Public Types inherited from Service
using Factory = Gaudi::PluginService::Factory< IService *(const std::string &, ISvcLocator *)>
 
- Public Types inherited from PropertyHolder< CommonMessaging< implements< IService, IProperty, IStateful > > >
using PropertyHolderImpl = PropertyHolder< CommonMessaging< implements< IService, IProperty, IStateful > > >
 Typedef used to refer to this class from derived classes, as in. More...
 
- Public Types inherited from CommonMessaging< implements< IService, IProperty, IStateful > >
using base_class = CommonMessaging
 
- Public Types inherited from extend_interfaces< Interfaces... >
using ext_iids = typename Gaudi::interface_list_cat< typename Interfaces::ext_iids... >::type
 take union of the ext_iids of all Interfaces... More...
 
- Protected Member Functions inherited from Service
std::vector< IAlgTool * > & tools ()
 
 ~Service () override
 Standard Destructor
More...
 
int outputLevel () const
 get the Service's output level More...
 
- Protected Member Functions inherited from CommonMessaging< implements< IService, IProperty, IStateful > >
MSG::Level setUpMessaging () const
 Set up local caches. More...
 
MSG::Level resetMessaging ()
 Reinitialize internal states. More...
 
void updateMsgStreamOutputLevel (int level)
 Update the output level of the cached MsgStream. More...
 
- Protected Attributes inherited from Service
Gaudi::StateMachine::State m_state = Gaudi::StateMachine::OFFLINE
 Service state
More...
 
Gaudi::StateMachine::State m_targetState = Gaudi::StateMachine::OFFLINE
 Service state
More...
 
Gaudi::Property< int > m_outputLevel { this, "OutputLevel", MSG::NIL, "output level" }
 flag indicating whether ToolHandle tools have been added to m_tools More...
 
Gaudi::Property< bool > m_auditInit { this, "AuditServices", false, "[[deprecated]] unused" }
 
Gaudi::Property< bool > m_auditorInitialize { this, "AuditInitialize", false, "trigger auditor on initialize()" }
 
Gaudi::Property< bool > m_auditorStart { this, "AuditStart", false, "trigger auditor on start()" }
 
Gaudi::Property< bool > m_auditorStop { this, "AuditStop", false, "trigger auditor on stop()" }
 
Gaudi::Property< bool > m_auditorFinalize { this, "AuditFinalize", false, "trigger auditor on finalize()" }
 
Gaudi::Property< bool > m_auditorReinitialize { this, "AuditReinitialize", false, "trigger auditor on reinitialize()" }
 
Gaudi::Property< bool > m_auditorRestart { this, "AuditRestart", false, "trigger auditor on restart()" }
 
Gaudi::Property< bool > m_autoRetrieveTools
 
Gaudi::Property< bool > m_checkToolDeps
 
SmartIF< IAuditorSvcm_pAuditorSvc
 Auditor Service
More...
 

Detailed Description

This service manages tools. Tools can be common, in which case a single instance can be shared by different algorithms, or private in which case it is necessary to specify the parent when requesting it. The parent of a tool can be an algortihm or a Service The environment of a tool is set by using that of the parent. A common tool is considered to belong to the ToolSvc itself.

Author
G. Corti, P. Mato

Definition at line 34 of file ToolSvc.h.

Member Typedef Documentation

◆ CallMutex

Definition at line 106 of file ToolSvc.h.

Constructor & Destructor Documentation

◆ ~ToolSvc()

ToolSvc::~ToolSvc ( )
override

Destructor.

Definition at line 56 of file ToolSvc.cpp.

56  {
57  // tell the remaining observers that we're gone, and forget about unregistering..
59  [&]( IToolSvc::Observer* obs ) { obs->setUnregister( {} ); } );
60 }

Member Function Documentation

◆ create() [1/2]

StatusCode ToolSvc::create ( const std::string type,
const IInterface parent,
IAlgTool *&  tool 
)

Create Tool standard way with automatically assigned name.

Definition at line 366 of file ToolSvc.cpp.

368 {
369  const std::string& toolname = tooltype;
370  return create( tooltype, toolname, parent, tool );
371 }

◆ create() [2/2]

StatusCode ToolSvc::create ( const std::string tooltype,
const std::string toolname,
const IInterface parent,
IAlgTool *&  tool 
)

Create Tool standard way with specified name.

Now able to handle clones.

The test of tool existence is performed according to three criteria: name, type and parent. If a tool is private, i.e. the parent is not the tool Svc, and it exist but the parent is not the specified one, a clone is handed over. No clones of public tools are allowed since they would be undistinguishable.

invoke create callbacks...

Definition at line 425 of file ToolSvc.cpp.

428 {
429 
430  auto lock = std::scoped_lock{ m_mut };
431  // protect against empty type
432  if ( tooltype.empty() ) {
433  error() << "create(): No Tool Type given" << endmsg;
434  return StatusCode::FAILURE;
435  }
436 
437  // If parent has not been specified, assume it is the ToolSvc
438  if ( !parent ) parent = this;
439 
440  tool = nullptr;
441  // Automatically deletes the tool if not explicitly kept (i.e. on success).
442  // The tool is removed from the list of known tools too.
443  auto toolguard = make_toolCreateGuard( m_instancesTools );
444 
445  // Check if the tool already exist : this could happen with clones
446  std::string fullname = nameTool( toolname, parent );
447  if ( existsTool( fullname ) ) {
448  // Now check if the parent is the same. This allows for clones
449  for ( IAlgTool* iAlgTool : m_instancesTools ) {
450  if ( iAlgTool->name() == toolname && iAlgTool->parent() == parent ) {
451  // The tool exist with this name, type and parent: this is bad!
452  // This excludes the possibility of cloning public tools intrinsecally
453  error() << "Tool " << fullname << " already exists with the same parent" << endmsg;
454  if ( parent == this )
455  error() << "... In addition, the parent is the ToolSvc: public tools cannot be cloned!" << endmsg;
456 
457  return StatusCode::FAILURE;
458  }
459  }
460  ON_DEBUG debug() << "Creating clone of " << fullname << endmsg;
461  }
462  // instantiate the tool using the factory
463  try {
464  toolguard.create( tooltype, fullname, parent );
465  if ( !toolguard.get() ) {
466  error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
467  return StatusCode::FAILURE;
468  }
469  } catch ( const GaudiException& Exception ) {
470  // (1) perform the printout of message
471  fatal() << "Exception with tag=" << Exception.tag() << " is caught whilst instantiating tool '" << tooltype << "'"
472  << endmsg;
473  // (2) print the exception itself
474  // (NB! - GaudiException is a linked list of all "previous exceptions")
475  fatal() << Exception << endmsg;
476  return StatusCode::FAILURE;
477  } catch ( const std::exception& Exception ) {
478  // (1) perform the printout of message
479  fatal() << "Standard std::exception is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
480  // (2) print the exception itself
481  // (NB! - GaudiException is a linked list of all "previous exceptions")
482  fatal() << Exception.what() << endmsg;
483  return StatusCode::FAILURE;
484  } catch ( ... ) {
485  // (1) perform the printout
486  fatal() << "UNKNOWN Exception is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
487  return StatusCode::FAILURE;
488  }
489  ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
490 
491  // Since only AlgTool has the setProperties() method it is necessary to cast
492  // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
493  // service
494  AlgTool* mytool = dynamic_cast<AlgTool*>( toolguard.get() );
495  if ( mytool ) mytool->bindPropertiesTo( serviceLocator()->getOptsSvc() );
496 
497  // Initialize the Tool
499  try {
500  sc = toolguard->sysInitialize();
501  }
502  // Catch any exceptions
503  catch ( const GaudiException& Exception ) {
504  error() << "GaudiException with tag=" << Exception.tag() << " caught whilst initializing tool '" << fullname << "'"
505  << endmsg << Exception << endmsg;
506  return StatusCode::FAILURE;
507  } catch ( const std::exception& Exception ) {
508  error() << "Standard std::exception caught whilst initializing tool '" << fullname << "'" << endmsg
509  << Exception.what() << endmsg;
510  return StatusCode::FAILURE;
511  } catch ( ... ) {
512  error() << "UNKNOWN Exception caught whilst initializing tool '" << fullname << "'" << endmsg;
513  return StatusCode::FAILURE;
514  }
515 
516  // Status of tool initialization
517  if ( sc.isFailure() ) {
518  error() << "Error initializing tool '" << fullname << "'" << endmsg;
519  return sc;
520  }
521 
522  // Start the tool if we are running.
524  sc = toolguard->sysStart();
525 
526  if ( sc.isFailure() ) {
527  error() << "Error starting tool '" << fullname << "'" << endmsg;
528  return sc;
529  }
530  }
531 
532  // The tool has been successfully created and initialized,
533  // so we inform the guard that it can release it
534  tool = toolguard.release();
535 
539  std::for_each( m_observers.begin(), m_observers.end(), [&]( IToolSvc::Observer* obs ) { obs->onCreate( tool ); } );
540  // TODO: replace by generic callback
541  // Register the tool with the HistorySvc
542  if ( m_pHistorySvc || service( "HistorySvc", m_pHistorySvc, false ).isSuccess() ) {
544  }
545  return StatusCode::SUCCESS;
546 }

◆ existsTool()

bool ToolSvc::existsTool ( std::string_view  toolname) const

Check if the tool instance exists.

Definition at line 568 of file ToolSvc.cpp.

570 {
571  auto lock = std::scoped_lock{ m_mut };
573  [&]( const IAlgTool* tool ) { return tool->name() == fullname; } );
574  return i != std::end( m_instancesTools );
575 }

◆ finalize()

StatusCode ToolSvc::finalize ( )
override

Finalize the service.

Algorithm: 2 passes. First pass:

  • do not explicitly release any tools
  • finalize tools, in the order of increasing number of refCounts Second pass:
  • explicitly release all tools, one release() on all tools per loop. -> tools are deleted in the order of increasing number of refCounts.

Inner loop: full loop over all left-over tools

  • finalize tools with the minimum number of refCounts in the list.
  • Remove finalized tools from list of tools, and add them to the list of finalized tools, to be deleted at the end. This way, any non-finalized tools who still reference already finalized tools in their finalize() will still find a live tool. Outer loop: keep on going until nothing changes in the list of tools. Checking for:
  • number of left-over tools
  • total number of refcounts
  • minimum number of refcounts

Definition at line 63 of file ToolSvc.cpp.

65 {
66  // Finalize and delete all left-over tools. Normally all tools created with
67  // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
68  // Several cases need to be covered:
69  // 1) Simple dependencies: no circular dependencies between tools,
70  // and tools not using other tools
71  // 2) Tools-using-tools (but no circular dependencies)
72  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
73  // b) release() is called in the tool destructor (e.g. via ToolHandle)
74  // 3) Circular dependencies between tools
75  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
76  // b) release() is called in the tool destructor (e.g. via ToolHandle)
77  // 4) In addition to each of the above cases, refCounting of a particular tool
78  // might not have been done correctly in the code. Typically release()
79  // is not called, so we are left with a too high refCount.
80  // What to do with those, and how to avoid a crash while handling them...
81 
90  info() << "Removing all tools created by ToolSvc" << endmsg;
91 
92  // Print out list of tools
93  ON_DEBUG {
94  auto& log = debug();
95  log << " Tool List : ";
96  for ( const auto& iTool : m_instancesTools ) { log << iTool->name() << ":" << iTool->refCount() << " "; }
97  log << endmsg;
98  }
99 
100  //
101  // first pass: Finalize all tools (but don't delete them)
102  //
115  boost::circular_buffer<IAlgTool*> finalizedTools( m_instancesTools.size() ); // list of tools that have been finalized
116  bool fail( false );
117  size_t toolCount = m_instancesTools.size();
118  unsigned long startRefCount = 0;
119  unsigned long endRefCount = totalToolRefCount();
120  unsigned long startMinRefCount = 0;
121  unsigned long endMinRefCount = minimumToolRefCount();
122  while ( toolCount > 0 && endRefCount > 0 && ( endRefCount != startRefCount || endMinRefCount != startMinRefCount ) ) {
123  ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
124  debug() << toolCount << " tools left to finalize. Summed refCounts: " << endRefCount << endmsg;
125  debug() << "Will finalize tools with refCount <= " << endMinRefCount << endmsg;
126  }
127  startMinRefCount = endMinRefCount;
128  startRefCount = endRefCount;
129  unsigned long maxLoop = toolCount + 1;
130  while ( --maxLoop > 0 && !m_instancesTools.empty() ) {
131  IAlgTool* pTool = m_instancesTools.back();
132  // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
134  unsigned long count = pTool->refCount();
135  // cache tool name
136  const std::string& toolName = pTool->name();
137  if ( count <= startMinRefCount ) {
138  ON_DEBUG debug() << " Performing finalization of " << toolName << " (refCount " << count << ")" << endmsg;
139  // finalize of one tool may trigger a release of another tool
140  // pTool->sysFinalize().ignore();
141  if ( !finalizeTool( pTool ).isSuccess() ) {
142  warning() << " FAILURE finalizing " << toolName << endmsg;
143  fail = true;
144  }
145  // postpone deletion
146  finalizedTools.push_back( pTool );
147  } else {
148  // Place back at the front of the list to try again later
149  // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
150  ON_DEBUG debug() << " Delaying finalization of " << toolName << " (refCount " << count << ")" << endmsg;
152  }
153  } // end of inner loop
154  toolCount = m_instancesTools.size();
155  endRefCount = totalToolRefCount();
156  endMinRefCount = minimumToolRefCount();
157  }; // end of outer loop
158 
159  //
160  // Second pass: Delete all finalized tools
161  //
162  // Delete in the order of increasing number of refCounts.
163  // Loop over tools in the same order as the order in which they were finalized.
164  // All tools in the list of finalized tools are no longer in the instancesTools list.
165  // If a tool destructor calls releaseTool() on another tool, this will have no
166  // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
167  // If this 'other tool' is still in the instancesTools list, it may trigger finalization
168  // (in releaseTool()), deletion and removal from the instancesTools list.
169  // Therefore, the check on non-finalised tools should happen *after* the deletion
170  // of the finalized tools.
171  ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
172  auto maxLoop = totalRefCount( finalizedTools ) + 1;
173  while ( --maxLoop > 0 && !finalizedTools.empty() ) {
174  IAlgTool* pTool = finalizedTools.front();
175  finalizedTools.pop_front();
176  auto count = pTool->refCount();
177  if ( count == 1 ) {
178  ON_DEBUG debug() << " Performing deletion of " << pTool->name() << endmsg;
179  } else {
180  ON_VERBOSE verbose() << " Delaying deletion of " << pTool->name() << " (refCount " << count << ")" << endmsg;
181  // Move to the end when refCount still not zero
182  finalizedTools.push_back( pTool );
183  }
184  // do a forced release
185  pTool->release();
186  }
187 
188  // Error if by now not all tools are properly finalised
189  if ( !m_instancesTools.empty() ) {
190  error() << "Unable to finalize and delete the following tools : ";
191  for ( const auto& iTool : m_instancesTools ) { error() << iTool->name() << ": " << iTool->refCount() << " "; }
192  error() << endmsg;
193  }
194 
195  // by now, all tools should be deleted and removed.
196  if ( !finalizedTools.empty() ) {
197  error() << "Failed to delete the following " << finalizedTools.size()
198  << " finalized tools. Bug in ToolSvc::finalize()?: ";
199  for ( const auto& iTool : finalizedTools ) { error() << iTool->name() << ": " << iTool->refCount() << " "; }
200  error() << endmsg;
201  }
202 
203  if ( m_pHistorySvc ) m_pHistorySvc->release();
204 
205  // Finalize this specific service
206  return ( Service::finalize().isSuccess() && !fail ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
207 }

◆ finalizeTool()

StatusCode ToolSvc::finalizeTool ( IAlgTool itool) const
private

Finalize the given tool, with exception handling.

Definition at line 578 of file ToolSvc.cpp.

580 {
581 
582  // Cache tool name in case of errors
583  const auto& toolName = itool->name();
584  StatusCode sc;
585 
586  // Finalise the tool inside a try block
587  try {
588  sc = itool->sysFinalize();
589  }
590  // Catch any exceptions
591  catch ( const GaudiException& Exception ) {
592  error() << "GaudiException with tag=" << Exception.tag() << " caught whilst finalizing tool '" << toolName << "'"
593  << endmsg << Exception << endmsg;
594  sc = StatusCode::FAILURE;
595  } catch ( const std::exception& Exception ) {
596  error() << "Standard std::exception caught whilst finalizing tool '" << toolName << "'" << endmsg
597  << Exception.what() << endmsg;
598  sc = StatusCode::FAILURE;
599  } catch ( ... ) {
600  error() << "UNKNOWN Exception caught whilst finalizing tool '" << toolName << "'" << endmsg;
601  sc = StatusCode::FAILURE;
602  }
603 
604  return sc;
605 }

◆ getInstances() [1/2]

std::vector< std::string > ToolSvc::getInstances ( ) const
override

Get names of all tool instances.

Definition at line 319 of file ToolSvc.cpp.

321 {
322  auto lock = std::scoped_lock{ m_mut };
325  []( const IAlgTool* t ) { return t->name(); } );
326  return tools;
327 }

◆ getInstances() [2/2]

std::vector< std::string > ToolSvc::getInstances ( std::string_view  toolType)
override

Get names of all tool instances of a given type.

Definition at line 307 of file ToolSvc.cpp.

309 {
310 
311  auto lock = std::scoped_lock{ m_mut };
313  for ( const auto& tool : m_instancesTools ) {
314  if ( tool->type() == toolType ) tools.push_back( tool->name() );
315  }
316  return tools;
317 }

◆ getTools()

std::vector< IAlgTool * > ToolSvc::getTools ( ) const
override

Get pointers to all tool instances.

Definition at line 329 of file ToolSvc.cpp.

331 {
332  auto lock = std::scoped_lock{ m_mut };
334 }

◆ minimumToolRefCount()

unsigned long ToolSvc::minimumToolRefCount ( ) const
private

The minimum number of refCounts of all tools.

Definition at line 614 of file ToolSvc.cpp.

616 {
617  auto i =
619  []( const IAlgTool* lhs, const IAlgTool* rhs ) { return lhs->refCount() < rhs->refCount(); } );
620  return i != std::end( m_instancesTools ) ? ( *i )->refCount() : 0;
621 }

◆ nameTool()

std::string ToolSvc::nameTool ( std::string_view  nameByUser,
const IInterface parent 
)

Get Tool full name by combining nameByUser and "parent" part.

Definition at line 549 of file ToolSvc.cpp.

551 {
552 
553  if ( !parent ) { return std::string{ this->name() }.append( "." ).append( toolname ); } // RETURN
554 
555  // check that parent has a name!
556  auto named_parent = SmartIF<INamedInterface>( const_cast<IInterface*>( parent ) );
557  if ( named_parent ) {
558  auto fullname = std::string{ named_parent->name() }.append( "." ).append( toolname );
559  return fullname; // RETURN
560  }
561 
562  error() << "Private Tools only allowed for components implementing INamedInterface" << endmsg;
563  //
564  return std::string{ "." }.append( toolname );
565 }

◆ registerObserver()

void ToolSvc::registerObserver ( IToolSvc::Observer obs)
override

Definition at line 624 of file ToolSvc.cpp.

624  {
625  //------------------------------------------------------------------------------
626  if ( !obs ) throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
627 
628  auto lock = std::scoped_lock{ m_mut };
629  obs->setUnregister( [this, obs]() {
630  auto lock = std::scoped_lock{ m_mut };
631  auto i = std::find( m_observers.begin(), m_observers.end(), obs );
632  if ( i != m_observers.end() ) m_observers.erase( i );
633  } );
634  m_observers.push_back( obs );
635 }

◆ releaseTool()

StatusCode ToolSvc::releaseTool ( IAlgTool tool)
override

Release tool.

Definition at line 336 of file ToolSvc.cpp.

338 {
339  auto lock = std::scoped_lock{ m_mut };
341  // test if tool is in known list (protect trying to access a previously deleted tool)
343  unsigned long count = tool->refCount();
344  if ( count == 1 ) {
345  // finalize the tool
346 
348  // We are being called during ToolSvc::finalize()
349  // message format matches the one in ToolSvc::finalize()
350  debug() << " Performing finalization of " << tool->name() << " (refCount " << count << ")" << endmsg;
351  // message format matches the one in ToolSvc::finalize()
352  debug() << " Performing deletion of " << tool->name() << endmsg;
353  } else {
354  debug() << "Performing finalization and deletion of " << tool->name() << endmsg;
355  }
356  sc = finalizeTool( tool );
357  // remove from known tools...
359  }
360  tool->release();
361  }
362  return sc;
363 }

◆ retrieve() [1/2]

StatusCode ToolSvc::retrieve ( std::string_view  tooltype,
std::string_view  toolname,
const InterfaceID iid,
IAlgTool *&  tool,
const IInterface parent,
bool  createIf 
)
override

Retrieve tool, create it by default as common tool if it does not already exist.

invoke retrieve callbacks...

Definition at line 243 of file ToolSvc.cpp.

246 {
247  // check the applicability of another method:
248  // ignore the provided name if it is empty or the type contains a name
249  if ( toolname.empty() || ( std::string_view::npos != tooltype.find( '/' ) ) ) {
250  return retrieve( tooltype, iid, tool, parent, createIf );
251  }
252 
253  // check for tools, which by name are required to be public:
254  if ( ba::ends_with( toolname, s_PUBLIC ) ) {
255  // parent for PUBLIC tool is this, i.e. ToolSvc
256  toolname.remove_suffix( s_PUBLIC.size() );
257  return retrieve( tooltype, toolname, iid, tool, this, createIf );
258  }
259 
260  auto lock = std::scoped_lock{ m_mut };
261 
262  IAlgTool* itool = nullptr;
264 
265  tool = nullptr;
266 
267  // If parent is not specified it means it is the ToolSvc itself
268  if ( !parent ) parent = this;
269  const std::string fullname = nameTool( toolname, parent );
270 
271  // Find tool in list of those already existing, and tell its
272  // interface that it has been used one more time
274  [&]( const IAlgTool* i ) { return i->name() == fullname && i->parent() == parent; } );
275  if ( it != std::end( m_instancesTools ) ) {
276  ON_DEBUG debug() << "Retrieved tool " << toolname << " with parent " << parent << endmsg;
277  itool = *it;
278  }
279 
280  if ( !itool ) {
281  // Instances of this tool do not exist, create an instance if desired
282  // otherwise return failure
283  if ( !createIf ) {
284  warning() << "Tool " << toolname << " not found and creation not requested" << endmsg;
285  return sc;
286  }
287  sc = create( std::string{ tooltype }, std::string{ toolname }, parent, itool );
288  if ( sc.isFailure() ) { return sc; }
289  }
290 
291  // Get the right interface of it
292  sc = itool->queryInterface( iid, pp_cast<void>( &tool ) );
293  if ( sc.isFailure() ) {
294  error() << "Tool " << toolname << " either does not implement the correct interface, or its version is incompatible"
295  << endmsg;
296  return sc;
297  }
298 
303  [&]( IToolSvc::Observer* obs ) { obs->onRetrieve( itool ); } );
304  return sc;
305 }

◆ retrieve() [2/2]

StatusCode ToolSvc::retrieve ( std::string_view  type,
const InterfaceID iid,
IAlgTool *&  tool,
const IInterface parent,
bool  createIf 
)
override

Retrieve tool, create it by default as common tool if it does not already exist.

Definition at line 219 of file ToolSvc.cpp.

222 {
223  // check for tools, which by name are required to be public:
224  if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
225  // parent for PUBLIC tool is 'this', i.e. ToolSvc
226  tooltype.remove_suffix( s_PUBLIC.size() );
227  return retrieve( tooltype, iid, tool, this, createIf );
228  }
229 
230  // protect against empty type
231  if ( tooltype.empty() ) {
232  error() << "retrieve(): No Tool Type/Name given" << endmsg;
233  return StatusCode::FAILURE;
234  }
235  auto pos = tooltype.find( '/' );
236  if ( std::string_view::npos == pos ) { return retrieve( tooltype, tooltype, iid, tool, parent, createIf ); }
237  return retrieve( tooltype.substr( 0, pos ), tooltype.substr( pos + 1 ), iid, tool, parent, createIf );
238 }

◆ start()

StatusCode ToolSvc::start ( )
override

Definition at line 638 of file ToolSvc.cpp.

640 {
641 
642  ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
643 
644  bool fail( false );
645  for ( auto& iTool : m_instancesTools ) {
646  ON_VERBOSE verbose() << iTool->name() << "::start()" << endmsg;
647 
648  if ( !iTool->sysStart().isSuccess() ) {
649  fail = true;
650  error() << iTool->name() << " failed to start()" << endmsg;
651  }
652  }
653 
654  if ( fail ) {
655  error() << "One or more AlgTools failed to start()" << endmsg;
656  return StatusCode::FAILURE;
657  }
658  return StatusCode::SUCCESS;
659 }

◆ stop()

StatusCode ToolSvc::stop ( )
override

Definition at line 662 of file ToolSvc.cpp.

664 {
665 
666  ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
667 
668  bool fail( false );
669  for ( auto& iTool : m_instancesTools ) {
670  ON_VERBOSE verbose() << iTool->name() << "::stop()" << endmsg;
671 
672  if ( !iTool->sysStop().isSuccess() ) {
673  fail = true;
674  error() << iTool->name() << " failed to stop()" << endmsg;
675  }
676  }
677 
678  if ( fail ) {
679  error() << "One or more AlgTools failed to stop()" << endmsg;
680  return StatusCode::FAILURE;
681  }
682  return StatusCode::SUCCESS;
683 }

◆ totalToolRefCount()

unsigned long ToolSvc::totalToolRefCount ( ) const
private

The total number of refCounts on all tools in the instancesTools list.

Definition at line 608 of file ToolSvc.cpp.

610 {
611  return totalRefCount( m_instancesTools );
612 }

Member Data Documentation

◆ m_instancesTools

std::vector<IAlgTool*> ToolSvc::m_instancesTools
private

Common Tools.

Definition at line 99 of file ToolSvc.h.

◆ m_mut

CallMutex ToolSvc::m_mut
mutableprivate

Definition at line 107 of file ToolSvc.h.

◆ m_observers

std::vector<IToolSvc::Observer*> ToolSvc::m_observers
private

Definition at line 104 of file ToolSvc.h.

◆ m_pHistorySvc

IHistorySvc* ToolSvc::m_pHistorySvc = nullptr
private

Pointer to HistorySvc.

Definition at line 102 of file ToolSvc.h.


The documentation for this class was generated from the following files:
ToolSvc::m_observers
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:104
ToolSvc::m_instancesTools
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:99
IHistorySvc::registerAlgTool
virtual StatusCode registerAlgTool(const IAlgTool &)=0
std::lock
T lock(T... args)
std::for_each
T for_each(T... args)
ToolSvc::finalizeTool
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:578
std::string
STL class.
IAlgTool
Definition: IAlgTool.h:33
ToolSvc::nameTool
std::string nameTool(std::string_view nameByUser, const IInterface *parent)
Get Tool full name by combining nameByUser and "parent" part.
Definition: ToolSvc.cpp:549
Gaudi.Configuration.log
log
Definition: Configuration.py:28
std::exception
STL class.
IToolSvc::Observer::setUnregister
void setUnregister(std::function< void()> unregister)
Definition: IToolSvc.h:235
Service::m_state
Gaudi::StateMachine::State m_state
Service state
Definition: Service.h:200
std::vector< std::string >
std::find_if
T find_if(T... args)
std::vector::size
T size(T... args)
GaudiException
Definition: GaudiException.h:31
IAlgTool::sysFinalize
virtual StatusCode sysFinalize()=0
Finalization of the Tool.
INamedInterface::name
virtual const std::string & name() const =0
Retrieve the name of the instance.
ToolSvc::existsTool
bool existsTool(std::string_view toolname) const
Check if the tool instance exists.
Definition: ToolSvc.cpp:568
IInterface::queryInterface
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
std::vector::back
T back(T... args)
ON_VERBOSE
#define ON_VERBOSE
Definition: ToolSvc.cpp:32
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:222
PropertyHolder::bindPropertiesTo
void bindPropertiesTo(Gaudi::Interfaces::IOptionsSvc &optsSvc)
Definition: PropertyHolder.h:252
std::vector::push_back
T push_back(T... args)
Service::tools
const std::vector< IAlgTool * > & tools() const
Definition: Service.cpp:409
bug_34121.t
t
Definition: bug_34121.py:30
bug_34121.tool
tool
Definition: bug_34121.py:17
Service::name
const std::string & name() const override
Retrieve name of the service
Definition: Service.cpp:332
StatusCode
Definition: StatusCode.h:65
ToolSvc::m_pHistorySvc
IHistorySvc * m_pHistorySvc
Pointer to HistorySvc.
Definition: ToolSvc.h:102
std::min_element
T min_element(T... args)
Gaudi::StateMachine::OFFLINE
@ OFFLINE
Definition: StateMachine.h:23
std::vector::erase
T erase(T... args)
GaudiPython.GaudiAlgs.iAlgTool
iAlgTool
Definition: GaudiAlgs.py:68
SmartIF< INamedInterface >
genconfuser.verbose
verbose
Definition: genconfuser.py:30
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
std::remove
T remove(T... args)
std::vector::pop_back
T pop_back(T... args)
std::transform
T transform(T... args)
Gaudi::StateMachine::RUNNING
@ RUNNING
Definition: StateMachine.h:26
IToolSvc::Observer
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:230
std::string::append
T append(T... args)
std::vector::rend
T rend(T... args)
StatusCode::ignore
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition: StatusCode.h:139
ToolSvc::create
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:366
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
ToolSvc::retrieve
StatusCode retrieve(std::string_view type, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent, bool createIf) override
Retrieve tool, create it by default as common tool if it does not already exist.
Definition: ToolSvc.cpp:219
IAlgTool::parent
virtual const IInterface * parent() const =0
The parent of the concrete AlgTool.
IToolSvc::Observer::onRetrieve
virtual void onRetrieve(const IAlgTool *)
Definition: IToolSvc.h:238
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
gaudirun.toolname
toolname
Definition: gaudirun.py:454
AlgTool
Definition: AlgTool.h:62
std::begin
T begin(T... args)
std::vector::insert
T insert(T... args)
IInterface
Definition: IInterface.h:237
std::count
T count(T... args)
std::string::empty
T empty(T... args)
Service::m_targetState
Gaudi::StateMachine::State m_targetState
Service state
Definition: Service.h:202
ToolSvc::minimumToolRefCount
unsigned long minimumToolRefCount() const
The minimum number of refCounts of all tools.
Definition: ToolSvc.cpp:614
ON_DEBUG
#define ON_DEBUG
Definition: ToolSvc.cpp:31
std::end
T end(T... args)
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
IInterface::refCount
virtual unsigned long refCount() const =0
Current reference count.
IInterface::release
virtual unsigned long release()=0
Release Interface instance.
Gaudi::Details::Property::ParsingErrorPolicy::Exception
@ Exception
ToolSvc::totalToolRefCount
unsigned long totalToolRefCount() const
The total number of refCounts on all tools in the instancesTools list.
Definition: ToolSvc.cpp:608
Service::service
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
Definition: Service.h:88
std::vector::rbegin
T rbegin(T... args)
Service::serviceLocator
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator
Definition: Service.cpp:335
ToolSvc::m_mut
CallMutex m_mut
Definition: ToolSvc.h:107