The Gaudi Framework  v40r0 (475e45c1)
ToolSvc Class Reference
Inheritance diagram for ToolSvc:
Collaboration diagram for ToolSvc:

Classes

class  ToolList
 Common Tools. More...
 

Public Member Functions

 ~ToolSvc () override
 
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::string > getInstances (std::string_view toolType) override
 Get names of all tool instances of a given type. More...
 
std::vector< std::string > getInstances () 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 fullname) 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 const * 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::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames. More...
 
- Public Member Functions inherited from Service
const std::string & name () 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<typename IFace = IService>
SmartIF< IFace > service (const std::string &name, bool createIf=true) const
 
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, const 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, Gaudi::Property< TYPE, VERIFIER, HANDLERS > &prop, const std::string &doc="none")
 Declare a PropertyBase instance setting name and documentation. More...
 
 requires (!Gaudi::Details::is_gaudi_property_v< TYPE >) Gaudi
 Helper to wrap a regular data member and use it as a regular property. 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 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 Member Functions

StatusCode finalizeTool (IAlgTool *itool) const
 Finalize the given tool, with exception handling. More...
 

Private Attributes

Gaudi::Property< bool > m_checkNamedToolsConfigured
 
Gaudi::Property< bool > m_showToolDataDeps { this, "ShowDataDeps", false, "show the data dependencies of AlgTools" }
 
std::recursive_mutex m_mut
 
ToolList m_instancesTools
 
SmartIF< IHistorySvcm_pHistorySvc
 Pointer to HistorySvc. More...
 
std::vector< IToolSvc::Observer * > m_observers
 

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
 
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_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 48 of file ToolSvc.cpp.

Constructor & Destructor Documentation

◆ ~ToolSvc()

ToolSvc::~ToolSvc ( )
override

Definition at line 201 of file ToolSvc.cpp.

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

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 479 of file ToolSvc.cpp.

479  {
480  const std::string& toolname = tooltype;
481  return create( tooltype, toolname, parent, tool );
482 }

◆ 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 535 of file ToolSvc.cpp.

536  {
537 
538  // protect against empty type
539  if ( tooltype.empty() ) {
540  error() << "create(): No Tool Type given" << endmsg;
541  return StatusCode::FAILURE;
542  }
543 
544  // If parent has not been specified, assume it is the ToolSvc
545  if ( !parent ) parent = this;
546 
547  tool = nullptr;
548  // Automatically deletes the tool if not explicitly kept (i.e. on success).
549  // The tool is removed from the list of known tools too.
550  auto lock = std::scoped_lock{ m_mut };
551  auto toolguard = make_toolCreateGuard( m_instancesTools );
552 
553  // Check if the tool already exist : this could happen with clones
554  std::string fullname = nameTool( toolname, parent );
555  if ( existsTool( fullname ) ) {
556  // Now check if the parent is the same. This allows for clones
557  for ( IAlgTool* iAlgTool : m_instancesTools ) {
558  if ( iAlgTool->name() == toolname && iAlgTool->parent() == parent ) {
559  // The tool exist with this name, type and parent: this is bad!
560  // This excludes the possibility of cloning public tools intrinsecally
561  error() << "Tool " << fullname << " already exists with the same parent" << endmsg;
562  if ( parent == this )
563  error() << "... In addition, the parent is the ToolSvc: public tools cannot be cloned!" << endmsg;
564 
565  return StatusCode::FAILURE;
566  }
567  }
568  ON_DEBUG debug() << "Creating clone of " << fullname << endmsg;
569  }
570  // instantiate the tool using the factory
571  try {
572  toolguard.create( tooltype, fullname, parent );
573  if ( !toolguard.get() ) {
574  error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
575  return StatusCode::FAILURE;
576  }
577  } catch ( const GaudiException& Exception ) {
578  // (1) perform the printout of message
579  fatal() << "Exception with tag=" << Exception.tag() << " is caught whilst instantiating tool '" << tooltype << "'"
580  << endmsg;
581  // (2) print the exception itself
582  // (NB! - GaudiException is a linked list of all "previous exceptions")
583  fatal() << Exception << endmsg;
584  return StatusCode::FAILURE;
585  } catch ( const std::exception& Exception ) {
586  // (1) perform the printout of message
587  fatal() << "Standard std::exception is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
588  // (2) print the exception itself
589  // (NB! - GaudiException is a linked list of all "previous exceptions")
590  fatal() << Exception.what() << endmsg;
591  return StatusCode::FAILURE;
592  } catch ( ... ) {
593  // (1) perform the printout
594  fatal() << "UNKNOWN Exception is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
595  return StatusCode::FAILURE;
596  }
597  ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
598 
599  // Since only AlgTool has the setProperties() method it is necessary to cast
600  // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
601  // service
602  AlgTool* mytool = dynamic_cast<AlgTool*>( toolguard.get() );
603  if ( mytool ) mytool->bindPropertiesTo( serviceLocator()->getOptsSvc() );
604 
605  // Initialize the Tool
607  try {
608  sc = toolguard->sysInitialize();
609  }
610  // Catch any exceptions
611  catch ( const GaudiException& Exception ) {
612  error() << "GaudiException with tag=" << Exception.tag() << " caught whilst initializing tool '" << fullname << "'"
613  << endmsg << Exception << endmsg;
614  return StatusCode::FAILURE;
615  } catch ( const std::exception& Exception ) {
616  error() << "Standard std::exception caught whilst initializing tool '" << fullname << "'" << endmsg
617  << Exception.what() << endmsg;
618  return StatusCode::FAILURE;
619  } catch ( ... ) {
620  error() << "UNKNOWN Exception caught whilst initializing tool '" << fullname << "'" << endmsg;
621  return StatusCode::FAILURE;
622  }
623 
624  // Status of tool initialization
625  if ( sc.isFailure() ) {
626  error() << "Error initializing tool '" << fullname << "'" << endmsg;
627  return sc;
628  }
629 
631  // Check to ensure that non-default named tools are configured.
632  if ( toolname != tooltype ) {
633  bool propsSet = false;
634  Gaudi::Interfaces::IOptionsSvc& joSvc = this->serviceLocator()->getOptsSvc();
635  // Check that at least one of the properties has been set:
636  for ( const auto prop : mytool->getProperties() ) {
637  bool isSet = joSvc.isSet( mytool->name() + "." + prop->name() );
638  if ( isSet ) propsSet = true;
639  }
640  if ( !propsSet ) {
641  warning() << tooltype << "/" << fullname
642  << " : Explicitly named tools should be configured! (assigned name=" << toolname << ", default is "
643  << tooltype << ")" << endmsg;
644  }
645  }
646  }
647 
648  // Start the tool if we are running.
650  sc = toolguard->sysStart();
651 
652  if ( sc.isFailure() ) {
653  error() << "Error starting tool '" << fullname << "'" << endmsg;
654  return sc;
655  }
656  }
657 
658  // The tool has been successfully created and initialized,
659  // so we inform the guard that it can release it
660  tool = toolguard.release();
661 
665  std::for_each( m_observers.begin(), m_observers.end(), [&]( IToolSvc::Observer* obs ) { obs->onCreate( tool ); } );
666  // TODO: replace by generic callback
667  // Register the tool with the HistorySvc
668  m_pHistorySvc = service( "HistorySvc", false );
669  if ( m_pHistorySvc ) { m_pHistorySvc->registerAlgTool( *tool ).ignore(); }
670  return StatusCode::SUCCESS;
671 }

◆ existsTool()

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

Check if the tool instance exists.

Definition at line 689 of file ToolSvc.cpp.

689  {
690  auto lock = std::scoped_lock{ m_mut };
691  return m_instancesTools.contains( fullname );
692 }

◆ 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 207 of file ToolSvc.cpp.

207  {
208  // Finalize and delete all left-over tools. Normally all tools created with
209  // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
210  // Several cases need to be covered:
211  // 1) Simple dependencies: no circular dependencies between tools,
212  // and tools not using other tools
213  // 2) Tools-using-tools (but no circular dependencies)
214  // a) release() is called in the tool::finalize() (e.g. via base class)
215  // b) release() is called in the tool destructor (e.g. via ToolHandle)
216  // 3) Circular dependencies between tools
217  // a) release() is called in the tool::finalize() (e.g. via base class)
218  // b) release() is called in the tool destructor (e.g. via ToolHandle)
219  // 4) In addition to each of the above cases, refCounting of a particular tool
220  // might not have been done correctly in the code. Typically release()
221  // is not called, so we are left with a too high refCount.
222  // What to do with those, and how to avoid a crash while handling them...
223 
232  info() << "Removing all tools created by ToolSvc" << endmsg;
233  auto tools = std::move( m_instancesTools ).grab();
234 
235  // Print out list of tools
236  ON_DEBUG {
237  auto& log = debug();
238  log << " Tool List : ";
239  for ( const auto& iTool : tools ) { log << iTool->name() << ":" << iTool->refCount() << " "; }
240  log << endmsg;
241  }
242 
243  //
244  // first pass: Finalize all tools (but don't delete them)
245  //
258  boost::circular_buffer<IAlgTool*> finalizedTools( tools.size() ); // list of tools that have been finalized
259  bool fail( false );
260  size_t toolCount = tools.size();
261  unsigned long startRefCount = 0;
262  unsigned long endRefCount = totalRefCount( tools );
263  unsigned long startMinRefCount = 0;
264  unsigned long endMinRefCount = minimumRefCount( tools );
265  while ( toolCount > 0 && endRefCount > 0 && ( endRefCount != startRefCount || endMinRefCount != startMinRefCount ) ) {
266  ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
267  debug() << toolCount << " tools left to finalize. Summed refCounts: " << endRefCount << endmsg;
268  debug() << "Will finalize tools with refCount <= " << endMinRefCount << endmsg;
269  }
270  startMinRefCount = endMinRefCount;
271  startRefCount = endRefCount;
272  unsigned long maxLoop = toolCount + 1;
273  while ( --maxLoop > 0 && !tools.empty() ) {
274  IAlgTool* pTool = tools.back();
275  // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
276  tools.pop_back();
277  unsigned long count = pTool->refCount();
278  // cache tool name
279  const std::string& toolName = pTool->name();
280  if ( count <= startMinRefCount ) {
281  ON_DEBUG debug() << " Performing finalization of " << toolName << " (refCount " << count << ")" << endmsg;
282  // finalize of one tool may trigger a release of another tool
283  // pTool->sysFinalize().ignore();
284  if ( !finalizeTool( pTool ).isSuccess() ) {
285  warning() << " FAILURE finalizing " << toolName << endmsg;
286  fail = true;
287  }
288  // postpone deletion
289  finalizedTools.push_back( pTool );
290  } else {
291  // Place back at the front of the list to try again later
292  // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
293  ON_DEBUG debug() << " Delaying finalization of " << toolName << " (refCount " << count << ")" << endmsg;
294  tools.insert( std::begin( tools ), pTool );
295  }
296  } // end of inner loop
297  toolCount = tools.size();
298  endRefCount = totalRefCount( tools );
299  endMinRefCount = minimumRefCount( tools );
300  }; // end of outer loop
301 
302  //
303  // Second pass: Delete all finalized tools
304  //
305  // Delete in the order of increasing number of refCounts.
306  // Loop over tools in the same order as the order in which they were finalized.
307  // All tools in the list of finalized tools are no longer in the instancesTools list.
308  // If a tool destructor calls releaseTool() on another tool, this will have no
309  // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
310  // If this 'other tool' is still in the instancesTools list, it may trigger finalization
311  // (in releaseTool()), deletion and removal from the instancesTools list.
312  // Therefore, the check on non-finalised tools should happen *after* the deletion
313  // of the finalized tools.
314  ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
315  auto maxLoop = totalRefCount( finalizedTools ) + 1;
316  while ( --maxLoop > 0 && !finalizedTools.empty() ) {
317  IAlgTool* pTool = finalizedTools.front();
318  finalizedTools.pop_front();
319  auto count = pTool->refCount();
320  if ( count == 1 ) {
321  ON_DEBUG debug() << " Performing deletion of " << pTool->name() << endmsg;
322  } else {
323  ON_VERBOSE verbose() << " Delaying deletion of " << pTool->name() << " (refCount " << count << ")" << endmsg;
324  // Move to the end when refCount still not zero
325  finalizedTools.push_back( pTool );
326  }
327  // do a forced release
328  pTool->release();
329  }
330 
331  // Error if by now not all tools are properly finalised
332  if ( !tools.empty() ) {
333  error() << "Unable to finalize and delete the following tools : ";
334  for ( const auto& iTool : tools ) { error() << iTool->name() << ": " << iTool->refCount() << " "; }
335  error() << endmsg;
336  }
337 
338  // by now, all tools should be deleted and removed.
339  if ( !finalizedTools.empty() ) {
340  error() << "Failed to delete the following " << finalizedTools.size()
341  << " finalized tools. Bug in ToolSvc::finalize()?: ";
342  for ( const auto& iTool : finalizedTools ) { error() << iTool->name() << ": " << iTool->refCount() << " "; }
343  error() << endmsg;
344  }
345 
346  // Finalize this specific service
347  return ( Service::finalize().isSuccess() && !fail ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
348 }

◆ finalizeTool()

StatusCode ToolSvc::finalizeTool ( IAlgTool itool) const
private

Finalize the given tool, with exception handling.

Definition at line 694 of file ToolSvc.cpp.

694  {
695 
696  // Cache tool name in case of errors
697  const auto& toolName = itool->name();
698  StatusCode sc;
699 
700  // Finalise the tool inside a try block
701  try {
702  sc = itool->sysFinalize();
703  }
704  // Catch any exceptions
705  catch ( const GaudiException& Exception ) {
706  error() << "GaudiException with tag=" << Exception.tag() << " caught whilst finalizing tool '" << toolName << "'"
707  << endmsg << Exception << endmsg;
708  sc = StatusCode::FAILURE;
709  } catch ( const std::exception& Exception ) {
710  error() << "Standard std::exception caught whilst finalizing tool '" << toolName << "'" << endmsg
711  << Exception.what() << endmsg;
712  sc = StatusCode::FAILURE;
713  } catch ( ... ) {
714  error() << "UNKNOWN Exception caught whilst finalizing tool '" << toolName << "'" << endmsg;
715  sc = StatusCode::FAILURE;
716  }
717 
718  return sc;
719 }

◆ getInstances() [1/2]

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

Get names of all tool instances.

Definition at line 439 of file ToolSvc.cpp.

439  {
440  auto lock = std::scoped_lock{ m_mut };
441  std::vector<std::string> tools{ m_instancesTools.size() };
443  []( const IAlgTool* t ) { return t->name(); } );
444  return tools;
445 }

◆ 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 429 of file ToolSvc.cpp.

429  {
430 
431  std::vector<std::string> tools;
432  auto lock = std::scoped_lock{ m_mut };
433  for ( const auto& tool : m_instancesTools ) {
434  if ( tool->type() == toolType ) tools.push_back( tool->name() );
435  }
436  return tools;
437 }

◆ getTools()

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

Get pointers to all tool instances.

Definition at line 447 of file ToolSvc.cpp.

447  {
448  auto lock = std::scoped_lock{ m_mut };
450 }

◆ 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 673 of file ToolSvc.cpp.

673  {
674 
675  if ( !parent ) { return std::string{ this->name() }.append( "." ).append( toolname ); }
676 
677  // check that parent has a name!
678  auto named_parent = SmartIF<INamedInterface>( const_cast<IInterface*>( parent ) );
679  if ( named_parent ) {
680  auto fullname = std::string{ named_parent->name() }.append( "." ).append( toolname );
681  return fullname;
682  }
683 
684  error() << "Private Tools only allowed for components implementing INamedInterface" << endmsg;
685  //
686  return std::string{ "." }.append( toolname );
687 }

◆ registerObserver()

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

Definition at line 721 of file ToolSvc.cpp.

721  {
722  if ( !obs ) throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
723 
724  auto lock = std::scoped_lock{ m_mut };
725  obs->setUnregister( [this, obs]() {
726  auto lock = std::scoped_lock{ m_mut };
727  auto i = std::find( m_observers.begin(), m_observers.end(), obs );
728  if ( i != m_observers.end() ) m_observers.erase( i );
729  } );
730  m_observers.push_back( obs );
731 }

◆ releaseTool()

StatusCode ToolSvc::releaseTool ( IAlgTool tool)
override

Release tool.

Definition at line 452 of file ToolSvc.cpp.

452  {
453  auto lock = std::scoped_lock{ m_mut };
455  // test if tool is in known list (protect trying to access a previously deleted tool)
456  if ( m_instancesTools.contains( tool ) ) {
457  unsigned long count = tool->refCount();
458  if ( count == 1 ) {
459  // finalize the tool
460 
462  // We are being called during ToolSvc::finalize()
463  // message format matches the one in ToolSvc::finalize()
464  debug() << " Performing finalization of " << tool->name() << " (refCount " << count << ")" << endmsg;
465  // message format matches the one in ToolSvc::finalize()
466  debug() << " Performing deletion of " << tool->name() << endmsg;
467  } else {
468  debug() << "Performing finalization and deletion of " << tool->name() << endmsg;
469  }
470  sc = finalizeTool( tool );
471  // remove from known tools...
473  }
474  tool->release();
475  }
476  return sc;
477 }

◆ 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 373 of file ToolSvc.cpp.

374  {
375  // check the applicability of another method:
376  // ignore the provided name if it is empty or the type contains a name
377  if ( toolname.empty() || ( std::string_view::npos != tooltype.find( '/' ) ) ) {
378  return retrieve( tooltype, iid, tool, parent, createIf );
379  }
380 
381  // check for tools, which by name are required to be public:
382  if ( ba::ends_with( toolname, s_PUBLIC ) ) {
383  // parent for PUBLIC tool is this, i.e. ToolSvc
384  toolname.remove_suffix( s_PUBLIC.size() );
385  return retrieve( tooltype, toolname, iid, tool, this, createIf );
386  }
387 
389 
390  tool = nullptr;
391 
392  // If parent is not specified it means it is the ToolSvc itself
393  if ( !parent ) parent = this;
394  const std::string fullname = nameTool( toolname, parent );
395 
396  // Find tool in list of those already existing, and tell its
397  // interface that it has been used one more time
398  auto lock = std::scoped_lock{ m_mut };
399  IAlgTool* itool = m_instancesTools.find( fullname, parent );
400  if ( itool ) { ON_DEBUG debug() << "Retrieved tool " << toolname << " with parent " << parent << endmsg; }
401 
402  if ( !itool ) {
403  // Instances of this tool do not exist, create an instance if desired
404  // otherwise return failure
405  if ( !createIf ) {
406  warning() << "Tool " << toolname << " not found and creation not requested" << endmsg;
407  return sc;
408  }
409  sc = create( std::string{ tooltype }, std::string{ toolname }, parent, itool );
410  if ( sc.isFailure() ) { return sc; }
411  }
412 
413  // Get the right interface of it
414  sc = itool->queryInterface( iid, pp_cast<void>( &tool ) );
415  if ( sc.isFailure() ) {
416  error() << "Tool " << toolname << " either does not implement the correct interface, or its version is incompatible"
417  << endmsg;
418  return sc;
419  }
420 
425  [&]( IToolSvc::Observer* obs ) { obs->onRetrieve( itool ); } );
426  return sc;
427 }

◆ 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 354 of file ToolSvc.cpp.

355  {
356  // check for tools, which by name are required to be public:
357  if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
358  // parent for PUBLIC tool is 'this', i.e. ToolSvc
359  tooltype.remove_suffix( s_PUBLIC.size() );
360  return retrieve( tooltype, iid, tool, this, createIf );
361  }
362 
363  // protect against empty type
364  if ( tooltype.empty() ) {
365  error() << "retrieve(): No Tool Type/Name given" << endmsg;
366  return StatusCode::FAILURE;
367  }
368  auto pos = tooltype.find( '/' );
369  if ( std::string_view::npos == pos ) { return retrieve( tooltype, tooltype, iid, tool, parent, createIf ); }
370  return retrieve( tooltype.substr( 0, pos ), tooltype.substr( pos + 1 ), iid, tool, parent, createIf );
371 }

◆ start()

StatusCode ToolSvc::start ( )
override

Definition at line 733 of file ToolSvc.cpp.

733  {
734 
735  ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
736 
737  if ( m_showToolDataDeps.value() ) {
738  info() << "Listing Data Dependencies of all Tools";
739  for ( auto& iTool : m_instancesTools ) {
740  IDataHandleHolder* idh = dynamic_cast<IDataHandleHolder*>( iTool );
741  if ( idh ) {
742  std::ostringstream ost;
743  for ( auto& dh : idh->inputHandles() ) { ost << "\n INPUT " << dh->fullKey(); }
744  for ( auto& id : idh->extraInputDeps() ) { ost << "\n EXTRA INPUT " << id; }
745  for ( auto& dh : idh->outputHandles() ) { ost << "\n OUTPUT " << dh->fullKey(); }
746  for ( auto& id : idh->extraOutputDeps() ) { ost << "\n EXTRA OUTPUT " << id; }
747  if ( ost.str().length() > 0 ) { info() << "\n" << iTool->name() << ost.str(); }
748  } else {
749  error() << "can't cast " << iTool->name() << " to IDataHandleHolder!" << endmsg;
750  }
751  }
752  info() << endmsg;
753  }
754 
755  bool fail( false );
756  for ( auto& iTool : m_instancesTools ) {
757  ON_VERBOSE verbose() << iTool->name() << "::start()" << endmsg;
758 
759  if ( !iTool->sysStart().isSuccess() ) {
760  fail = true;
761  error() << iTool->name() << " failed to start()" << endmsg;
762  }
763  }
764 
765  if ( fail ) {
766  error() << "One or more AlgTools failed to start()" << endmsg;
767  return StatusCode::FAILURE;
768  }
769  return StatusCode::SUCCESS;
770 }

◆ stop()

StatusCode ToolSvc::stop ( )
override

Definition at line 772 of file ToolSvc.cpp.

772  {
773 
774  ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
775 
776  bool fail( false );
777  for ( auto& iTool : m_instancesTools ) {
778  ON_VERBOSE verbose() << iTool->name() << "::stop()" << endmsg;
779 
780  if ( !iTool->sysStop().isSuccess() ) {
781  fail = true;
782  error() << iTool->name() << " failed to stop()" << endmsg;
783  }
784  }
785 
786  if ( fail ) {
787  error() << "One or more AlgTools failed to stop()" << endmsg;
788  return StatusCode::FAILURE;
789  }
790  return StatusCode::SUCCESS;
791 }

Member Data Documentation

◆ m_checkNamedToolsConfigured

Gaudi::Property<bool> ToolSvc::m_checkNamedToolsConfigured
private
Initial value:
{
this, "CheckedNamedToolsConfigured", false,
"Check that tools which do not have the default name have some explicit configuration." }

Definition at line 102 of file ToolSvc.cpp.

◆ m_instancesTools

ToolList ToolSvc::m_instancesTools
private

Definition at line 174 of file ToolSvc.cpp.

◆ m_mut

std::recursive_mutex ToolSvc::m_mut
mutableprivate

Definition at line 173 of file ToolSvc.cpp.

◆ m_observers

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

Definition at line 179 of file ToolSvc.cpp.

◆ m_pHistorySvc

SmartIF<IHistorySvc> ToolSvc::m_pHistorySvc
private

Pointer to HistorySvc.

Definition at line 177 of file ToolSvc.cpp.

◆ m_showToolDataDeps

Gaudi::Property<bool> ToolSvc::m_showToolDataDeps { this, "ShowDataDeps", false, "show the data dependencies of AlgTools" }
private

Definition at line 106 of file ToolSvc.cpp.


The documentation for this class was generated from the following file:
IDataHandleHolder
Definition: IDataHandleHolder.h:23
ToolSvc::m_observers
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.cpp:179
ToolSvc::m_mut
std::recursive_mutex m_mut
Definition: ToolSvc.cpp:173
ToolSvc::finalizeTool
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:694
IAlgTool
Definition: IAlgTool.h:29
ToolSvc::m_pHistorySvc
SmartIF< IHistorySvc > m_pHistorySvc
Pointer to HistorySvc.
Definition: ToolSvc.cpp:177
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:673
Gaudi.Configuration.log
log
Definition: Configuration.py:28
IToolSvc::Observer::setUnregister
void setUnregister(std::function< void()> unregister)
Definition: IToolSvc.h:234
IDataHandleHolder::extraInputDeps
virtual const DataObjIDColl & extraInputDeps() const =0
Service::m_state
Gaudi::StateMachine::State m_state
Service state
Definition: Service.h:155
ToolSvc::existsTool
bool existsTool(std::string_view fullname) const
Check if the tool instance exists.
Definition: ToolSvc.cpp:689
GaudiException
Definition: GaudiException.h:29
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.
IInterface::queryInterface
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
Service::service
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
Definition: Service.h:79
ON_VERBOSE
#define ON_VERBOSE
Definition: ToolSvc.cpp:33
GaudiPartProp.tests.id
id
Definition: tests.py:111
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:223
AlgTool::name
const std::string & name() const override
Retrieve full identifying name of the concrete tool object.
Definition: AlgTool.cpp:72
ToolSvc::ToolList::contains
bool contains(std::string_view name) const
Definition: ToolSvc.cpp:148
PropertyHolder::bindPropertiesTo
void bindPropertiesTo(Gaudi::Interfaces::IOptionsSvc &optsSvc)
Definition: PropertyHolder.h:238
Service::tools
const std::vector< IAlgTool * > & tools() const
Definition: Service.cpp:411
PropertyHolder::getProperties
const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const override
get all properties
Definition: PropertyHolder.h:210
bug_34121.t
t
Definition: bug_34121.py:31
bug_34121.tool
tool
Definition: bug_34121.py:18
Gaudi::Utils::begin
AttribStringParser::Iterator begin(const AttribStringParser &parser)
Definition: AttribStringParser.h:135
Service::name
const std::string & name() const override
Retrieve name of the service
Definition: Service.cpp:333
StatusCode
Definition: StatusCode.h:64
Gaudi::cxx::for_each
void for_each(ContainerOfSynced &c, Fun &&f)
Definition: SynchronizedValue.h:98
IDataHandleHolder::extraOutputDeps
virtual const DataObjIDColl & extraOutputDeps() const =0
Gaudi::StateMachine::OFFLINE
@ OFFLINE
Definition: StateMachine.h:22
ToolSvc::m_checkNamedToolsConfigured
Gaudi::Property< bool > m_checkNamedToolsConfigured
Definition: ToolSvc.cpp:102
Gaudi::Property::value
const ValueType & value() const
Definition: Property.h:229
ToolSvc::ToolList::remove
void remove(IAlgTool *tool)
Definition: ToolSvc.cpp:129
SmartIF
Definition: IConverter.h:22
genconfuser.verbose
verbose
Definition: genconfuser.py:28
ToolSvc::ToolList::find
auto find(std::string_view name, const IInterface *parent) const
Definition: ToolSvc.cpp:156
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:198
IDataHandleHolder::inputHandles
virtual std::vector< Gaudi::DataHandle * > inputHandles() const =0
Gaudi::StateMachine::RUNNING
@ RUNNING
Definition: StateMachine.h:25
IToolSvc::Observer
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:229
ToolSvc::create
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:479
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:354
IToolSvc::Observer::onRetrieve
virtual void onRetrieve(const IAlgTool *)
Definition: IToolSvc.h:237
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:99
gaudirun.toolname
toolname
Definition: gaudirun.py:454
ToolSvc::ToolList::size
auto size() const
Definition: ToolSvc.cpp:153
AlgTool
Definition: AlgTool.h:55
IInterface
Definition: IInterface.h:225
IDataHandleHolder::outputHandles
virtual std::vector< Gaudi::DataHandle * > outputHandles() const =0
Service::m_targetState
Gaudi::StateMachine::State m_targetState
Service state
Definition: Service.h:157
ON_DEBUG
#define ON_DEBUG
Definition: ToolSvc.cpp:32
IOTest.end
end
Definition: IOTest.py:125
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:100
IInterface::refCount
virtual unsigned long refCount() const =0
Current reference count.
Gaudi::Details::Property::ParsingErrorPolicy::Exception
@ Exception
ToolSvc::m_instancesTools
ToolList m_instancesTools
Definition: ToolSvc.cpp:174
Gaudi::Interfaces::IOptionsSvc
Interface for a component that manages application configuration options.
Definition: IOptionsSvc.h:46
ToolSvc::m_showToolDataDeps
Gaudi::Property< bool > m_showToolDataDeps
Definition: ToolSvc.cpp:106
IInterface::release
virtual unsigned long release() const =0
Release Interface instance.
Service::serviceLocator
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator
Definition: Service.cpp:336
Gaudi::Interfaces::IOptionsSvc::isSet
virtual bool isSet(const std::string &key) const =0
Test if an option key was explicitly set or not.