ToolSvc Class Reference

This service manages tools. More...

#include <src/ApplicationMgr/ToolSvc.h>

Inheritance diagram for ToolSvc:
Collaboration diagram for ToolSvc:

Public Member Functions

StatusCode initialize () override
 Initialize the service. More...
 
StatusCode finalize () override
 Finalize the service. More...
 
StatusCode start () override
 
StatusCode stop () override
 
StatusCode retrieve (const std::string &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 (const std::string &tooltype, const std::string &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 (const std::string &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 (const std::string &toolname) const
 Check if the tool instance exists. More...
 
std::string nameTool (const std::string &nameByUser, const IInterface *parent)
 Get Tool full name by combining nameByUser and "parent" part. More...
 
 ToolSvc (const std::string &name, ISvcLocator *svc)
 Standard Constructor. More...
 
 ~ToolSvc () override=default
 Destructor. More...
 
void registerObserver (IToolSvc::Observer *obs) override
 
void unRegisterObserver (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...
 
 ~extends () override=default
 Virtual destructor. 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...
 
StatusCode setProperty (const Property &p) override
 
StatusCode setProperty (const std::string &s) override
 
StatusCode setProperty (const std::string &n, const std::string &v) override
 
StatusCode getProperty (Property *p) const override
 
const PropertygetProperty (const std::string &name) const override
 
StatusCode getProperty (const std::string &n, std::string &v) const override
 
const std::vector< Property * > & getProperties () const override
 
bool hasProperty (const std::string &name) const override
 
template<class TYPE >
StatusCode setProperty (const std::string &name, const TYPE &value)
 set the property form the value More...
 
 Service (std::string name, ISvcLocator *svcloc)
 Standard Constructor. More...
 
SmartIF< ISvcLocator > & serviceLocator () const override
 Retrieve pointer to service locator. More...
 
StatusCode setProperties ()
 Method for setting declared properties to the values specified for the job. 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 >
PropertydeclareProperty (const std::string &name, T &property, const std::string &doc="none") const
 Declare the named property. More...
 
PropertydeclareRemoteProperty (const std::string &name, IProperty *rsvc, const std::string &rname="") const
 Declare remote named properties. More...
 
template<class T >
StatusCode declarePrivateTool (ToolHandle< T > &handle, std::string toolTypeAndName="", bool createIf=true)
 Declare used Private tool. More...
 
template<class T >
StatusCode declarePublicTool (ToolHandle< T > &handle, std::string toolTypeAndName="", bool createIf=true)
 Declare used Public tool. More...
 
SmartIF< IAuditorSvc > & auditorSvc () const
 The standard auditor service.May not be invoked before sysInitialize() has been invoked. More...
 
- Public Member Functions inherited from CommonMessagingBase
virtual ~CommonMessagingBase ()=default
 Virtual destructor. More...
 
SmartIF< IMessageSvc > & msgSvc () const
 The standard message service. More...
 
MsgStreammsgStream () const
 Return an uninitialized MsgStream. More...
 
MsgStreammsgStream (const MSG::Level level) const
 Predefined configurable message stream for the efficient printouts. More...
 
MsgStreamalways () const
 shortcut for the method msgStream(MSG::ALWAYS) More...
 
MsgStreamfatal () const
 shortcut for the method msgStream(MSG::FATAL) More...
 
MsgStreamerr () const
 shortcut for the method msgStream(MSG::ERROR) More...
 
MsgStreamerror () const
 shortcut for the method msgStream(MSG::ERROR) More...
 
MsgStreamwarning () const
 shortcut for the method msgStream(MSG::WARNING) More...
 
MsgStreaminfo () const
 shortcut for the method msgStream(MSG::INFO) More...
 
MsgStreamdebug () const
 shortcut for the method msgStream(MSG::DEBUG) More...
 
MsgStreamverbose () const
 shortcut for the method msgStream(MSG::VERBOSE) More...
 
MsgStreammsg () const
 shortcut for the method msgStream(MSG::INFO) More...
 
MSG::Level msgLevel () const
 get the output level from the embedded MsgStream More...
 
MSG::Level outputLevel () const __attribute__((deprecated))
 Backward compatibility function for getting the output level. More...
 
bool msgLevel (MSG::Level lvl) const
 get the output level from the embedded MsgStream More...
 
- Public Member Functions inherited from extend_interfaces< Interfaces...>
 ~extend_interfaces () override=default
 Virtual destructor. 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
typedef Gaudi::PluginService::Factory< IService *, const std::string &, ISvcLocator * > Factory
 
- 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
 ~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 > >
void updateMsgStreamOutputLevel (int level)
 Update the output level of the cached MsgStream. More...
 
- Protected Attributes inherited from Service
IntegerProperty m_outputLevel = MSG::NIL
 Service output level. More...
 
Gaudi::StateMachine::State m_state = Gaudi::StateMachine::OFFLINE
 Service state. More...
 
Gaudi::StateMachine::State m_targetState = Gaudi::StateMachine::OFFLINE
 Service state. 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 23 of file ToolSvc.h.

Member Typedef Documentation

Definition at line 110 of file ToolSvc.h.

Constructor & Destructor Documentation

ToolSvc::ToolSvc ( const std::string name,
ISvcLocator svc 
)

Standard Constructor.

Parameters
nameString with service name
svcPointer to service locator interface

Definition at line 47 of file ToolSvc.cpp.

49  : base_class( name, svc) { }
extends base_class
Typedef to this class.
Definition: extends.h:14
ToolSvc::~ToolSvc ( )
overridedefault

Destructor.

Member Function Documentation

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

Create Tool standard way with automatically assigned name.

Definition at line 414 of file ToolSvc.cpp.

418 {
419  const std::string & toolname = tooltype;
420  return create( tooltype, toolname, parent, tool);
421 }
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:414
tuple toolname
Definition: gaudirun.py:327
STL class.
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 479 of file ToolSvc.cpp.

484 {
485 
487  // protect against empty type
488  if ( UNLIKELY(tooltype.empty()) ) {
489  error() << "create(): No Tool Type given" << endmsg;
490  return StatusCode::FAILURE;
491  }
492 
493  // If parent has not been specified, assume it is the ToolSvc
494  if ( !parent ) parent = this;
495 
496  tool = nullptr;
497  // Automatically deletes the tool if not explicitly kept (i.e. on success).
498  // The tool is removed from the list of known tools too.
499  auto toolguard = make_toolCreateGuard(m_instancesTools);
500 
501  // Check if the tool already exist : this could happen with clones
502  std::string fullname = nameTool(toolname, parent);
503  if( UNLIKELY(existsTool(fullname)) ) {
504  // Now check if the parent is the same. This allows for clones
506  if ( iAlgTool->name() == toolname && iAlgTool->parent() == parent){
507  // The tool exist with this name, type and parent: this is bad!
508  // This excludes the possibility of cloning public tools intrinsecally
509  error() << "Tool " << fullname << " already exists with the same parent" << endmsg;
510  if (parent == this)
511  error() << "... In addition, the parent is the ToolSvc: public tools cannot be cloned!" << endmsg;
512 
513  return StatusCode::FAILURE;
514  }
515  }
516  ON_DEBUG debug() << "Creating clone of " << fullname << endmsg;
517  }
518  // instantiate the tool using the factory
519  try {
520  toolguard.create( tooltype, fullname, parent );
521  if ( UNLIKELY(! toolguard.get()) ){
522  error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
523  return StatusCode::FAILURE;
524  }
525  }
526  catch ( const GaudiException& Exception ) {
527  // (1) perform the printout of message
528  fatal() << "Exception with tag=" << Exception.tag()
529  << " is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
530  // (2) print the exception itself
531  // (NB! - GaudiException is a linked list of all "previous exceptions")
532  fatal() << Exception << endmsg;
533  return StatusCode::FAILURE;
534  }
535  catch( const std::exception& Exception ) {
536  // (1) perform the printout of message
537  fatal() << "Standard std::exception is caught whilst instantiating tool '"
538  << tooltype << "'" << endmsg;
539  // (2) print the exception itself
540  // (NB! - GaudiException is a linked list of all "previous exceptions")
541  fatal() << Exception.what() << endmsg;
542  return StatusCode::FAILURE;
543  }
544  catch(...) {
545  // (1) perform the printout
546  fatal() << "UNKNOWN Exception is caught whilst instantiating tool '"
547  << tooltype << "'" << endmsg;
548  return StatusCode::FAILURE;
549  }
550  ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
551 
552  // Since only AlgTool has the setProperties() method it is necessary to cast
553  // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
554  // service
555  AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get());
556  if ( mytool ) {
557  StatusCode sc = mytool->setProperties();
558  if ( UNLIKELY(sc.isFailure()) ) {
559  error() << "Error setting properties for tool '"
560  << fullname << "'" << endmsg;
561  return sc;
562  }
563  }
564 
565  // Initialize the Tool
567  try {
568  sc = toolguard->sysInitialize();
569  }
570  // Catch any exceptions
571  catch ( const GaudiException & Exception )
572  {
573  error()
574  << "GaudiException with tag=" << Exception.tag()
575  << " caught whilst initializing tool '" << fullname << "'" << endmsg
576  << Exception << endmsg;
577  return StatusCode::FAILURE;
578  }
579  catch( const std::exception & Exception )
580  {
581  error()
582  << "Standard std::exception caught whilst initializing tool '"
583  << fullname << "'" << endmsg << Exception.what() << endmsg;
584  return StatusCode::FAILURE;
585  }
586  catch (...)
587  {
588  error()
589  << "UNKNOWN Exception caught whilst initializing tool '"
590  << fullname << "'" << endmsg;
591  return StatusCode::FAILURE;
592  }
593 
594  // Status of tool initialization
595  if ( UNLIKELY(sc.isFailure()) ) {
596  error() << "Error initializing tool '" << fullname << "'" << endmsg;
597  return sc;
598  }
599 
600  // Start the tool if we are running.
602  sc = toolguard->sysStart();
603 
604  if (UNLIKELY(sc.isFailure())) {
605  error() << "Error starting tool '" << fullname << "'" << endmsg;
606  return sc;
607  }
608  }
609 
610 
611  // The tool has been successfully created and initialized,
612  // so we inform the guard that it can release it
613  tool = toolguard.release();
614 
619  m_observers.end(),
620  [&](IToolSvc::Observer* obs) { obs->onCreate(tool); } );
621  // TODO: replace by generic callback
622  // Register the tool with the HistorySvc
623  if (m_pHistorySvc || service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
625  }
626  return StatusCode::SUCCESS;
627 
628 }
IHistorySvc * m_pHistorySvc
Pointer to HistorySvc.
Definition: ToolSvc.h:106
#define UNLIKELY(x)
Definition: Kernel.h:126
T empty(T...args)
Define general base for Gaudi exception.
Gaudi::StateMachine::State m_state
Service state.
Definition: Service.h:311
std::string nameTool(const std::string &nameByUser, const IInterface *parent)
Get Tool full name by combining nameByUser and "parent" part.
Definition: ToolSvc.cpp:631
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:244
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
T end(T...args)
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:108
bool existsTool(const std::string &toolname) const
Check if the tool instance exists.
Definition: ToolSvc.cpp:653
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
StatusCode setProperties()
Method for setting declared properties to the values specified in the jobOptions via the job option s...
Definition: AlgTool.cpp:171
STL class.
virtual void onCreate(const IAlgTool *)
Definition: IToolSvc.h:247
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
T what(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
virtual StatusCode registerAlgTool(const IAlgTool &)=0
def lock(file)
Definition: locker.py:16
virtual const std::string & tag() const
name tag for the exception, or exception type
STL class.
virtual unsigned long release()=0
Release Interface instance.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
T begin(T...args)
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:45
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
#define ON_DEBUG
Definition: ToolSvc.cpp:20
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:144
void ignore() const
Definition: StatusCode.h:108
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
CallMutex m_mut
Definition: ToolSvc.h:111
T for_each(T...args)
#define ON_VERBOSE
Definition: ToolSvc.cpp:21
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
bool ToolSvc::existsTool ( const std::string toolname) const

Check if the tool instance exists.

Definition at line 653 of file ToolSvc.cpp.

655 {
658  [&](const IAlgTool* tool) { return tool->name() == fullname; } );
659  return i != std::end(m_instancesTools);
660 }
T end(T...args)
virtual const std::string & name() const =0
Retrieve the name of the instance.
def lock(file)
Definition: locker.py:16
T find_if(T...args)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
T begin(T...args)
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
CallMutex m_mut
Definition: ToolSvc.h:111
list i
Definition: ana.py:128
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 74 of file ToolSvc.cpp.

76 {
77  // Finalize and delete all left-over tools. Normally all tools created with
78  // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
79  // Several cases need to be covered:
80  // 1) Simple dependencies: no circular dependencies between tools,
81  // and tools not using other tools
82  // 2) Tools-using-tools (but no circular dependencies)
83  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
84  // b) release() is called in the tool destructor (e.g. via ToolHandle)
85  // 3) Circular dependencies between tools
86  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
87  // b) release() is called in the tool destructor (e.g. via ToolHandle)
88  // 4) In addition to each of the above cases, refCounting of a particular tool
89  // might not have been done correctly in the code. Typically release()
90  // is not called, so we are left with a too high refCount.
91  // What to do with those, and how to avoid a crash while handling them...
92 
101  info() << "Removing all tools created by ToolSvc" << endmsg;
102 
103  // Print out list of tools
104  ON_DEBUG {
105  auto &log = debug();
106  log << " Tool List : ";
107  for ( const auto& iTool : m_instancesTools ) {
108  log << iTool->name() << ":" << iTool->refCount( ) << " ";
109  }
110  log << endmsg;
111  }
112 
113  //
114  // first pass: Finalize all tools (but don't delete them)
115  //
128  boost::circular_buffer<IAlgTool*> finalizedTools(m_instancesTools.size()); // list of tools that have been finalized
129  bool fail(false);
130  size_t toolCount = m_instancesTools.size();
131  unsigned long startRefCount = 0;
132  unsigned long endRefCount = totalToolRefCount();
133  unsigned long startMinRefCount = 0;
134  unsigned long endMinRefCount = minimumToolRefCount();
135  while ( toolCount > 0 &&
136  endRefCount > 0 &&
137  (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) {
138  ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
139  debug() << toolCount << " tools left to finalize. Summed refCounts: "
140  << endRefCount << endmsg;
141  debug() << "Will finalize tools with refCount <= "
142  << endMinRefCount << endmsg;
143  }
144  startMinRefCount = endMinRefCount;
145  startRefCount = endRefCount;
146  unsigned long maxLoop = toolCount + 1;
147  while ( --maxLoop > 0 && !m_instancesTools.empty() ) {
148  IAlgTool* pTool = m_instancesTools.back();
149  // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
150  m_instancesTools.pop_back();
151  unsigned long count = pTool->refCount( );
152  // cache tool name
153  const std::string& toolName = pTool->name();
154  if ( count <= startMinRefCount ) {
155  ON_DEBUG debug() << " Performing finalization of " << toolName
156  << " (refCount " << count << ")" << endmsg;
157  // finalize of one tool may trigger a release of another tool
158  // pTool->sysFinalize().ignore();
159  if (!finalizeTool(pTool).isSuccess()) {
160  warning() << " FAILURE finalizing " << toolName << endmsg;
161  fail = true;
162  }
163  // postpone deletion
164  finalizedTools.push_back(pTool);
165  } else {
166  // Place back at the front of the list to try again later
167  // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
168  ON_DEBUG debug() << " Delaying finalization of " << toolName
169  << " (refCount " << count << ")" << endmsg;
170  m_instancesTools.insert( std::begin(m_instancesTools), pTool );
171  }
172  } // end of inner loop
173  toolCount = m_instancesTools.size();
174  endRefCount = totalToolRefCount();
175  endMinRefCount = minimumToolRefCount();
176  }; // end of outer loop
177 
178  //
179  // Second pass: Delete all finalized tools
180  //
181  // Delete in the order of increasing number of refCounts.
182  // Loop over tools in the same order as the order in which they were finalized.
183  // All tools in the list of finalized tools are no longer in the instancesTools list.
184  // If a tool destructor calls releaseTool() on another tool, this will have no
185  // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
186  // If this 'other tool' is still in the instancesTools list, it may trigger finalization
187  // (in releaseTool()), deletion and removal from the instancesTools list.
188  // Therefore, the check on non-finalised tools should happen *after* the deletion
189  // of the finalized tools.
190  ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
191  auto maxLoop = totalRefCount( finalizedTools ) + 1;
192  while ( --maxLoop > 0 && !finalizedTools.empty() ) {
193  IAlgTool* pTool = finalizedTools.front();
194  finalizedTools.pop_front();
195  auto count = pTool->refCount( );
196  if ( count == 1 ) {
197  ON_DEBUG debug() << " Performing deletion of " << pTool->name() << endmsg;
198  } else {
199  ON_VERBOSE verbose() << " Delaying deletion of " << pTool->name()
200  << " (refCount " << count << ")" << endmsg;
201  // Move to the end when refCount still not zero
202  finalizedTools.push_back(pTool);
203  }
204  // do a forced release
205  pTool->release();
206  }
207 
208  // Error if by now not all tools are properly finalised
209  if ( !m_instancesTools.empty() ) {
210  error() << "Unable to finalize and delete the following tools : ";
211  for ( const auto& iTool : m_instancesTools ) {
212  error() << iTool->name() << ": " << iTool->refCount( ) << " ";
213  }
214  error() << endmsg;
215  }
216 
217  // by now, all tools should be deleted and removed.
218  if ( !finalizedTools.empty() ) {
219  error() << "Failed to delete the following " << finalizedTools.size()
220  << " finalized tools. Bug in ToolSvc::finalize()?: ";
221  for ( const auto& iTool : finalizedTools ) {
222  error() << iTool->name() << ": " << iTool->refCount( ) << " ";
223  }
224  error() << endmsg;
225  }
226 
227  if ( m_pHistorySvc ) m_pHistorySvc->release();
228 
229  // Finalize this specific service
230  return ( Service::finalize().isSuccess() && !fail ) ?
233 
234 }
IHistorySvc * m_pHistorySvc
Pointer to HistorySvc.
Definition: ToolSvc.h:106
StatusCode finalize() override
Definition: Service.cpp:193
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
unsigned long minimumToolRefCount() const
The minimum number of refCounts of all tools.
Definition: ToolSvc.cpp:710
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
virtual const std::string & name() const =0
Retrieve the name of the instance.
STL class.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
unsigned long totalToolRefCount() const
The total number of refCounts on all tools in the instancesTools list.
Definition: ToolSvc.cpp:704
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:663
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
virtual unsigned long refCount() const =0
Current reference count.
T count(T...args)
virtual unsigned long release()=0
Release Interface instance.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
T begin(T...args)
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
#define ON_DEBUG
Definition: ToolSvc.cpp:20
#define ON_VERBOSE
Definition: ToolSvc.cpp:21
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode ToolSvc::finalizeTool ( IAlgTool itool) const
private

Finalize the given tool, with exception handling.

Definition at line 663 of file ToolSvc.cpp.

665 {
666 
667  // Cache tool name in case of errors
668  const std::string toolName = itool->name();
669  StatusCode sc;
670 
671  // Finalise the tool inside a try block
672  try {
673  sc = itool->sysFinalize();
674  }
675  // Catch any exceptions
676  catch ( const GaudiException & Exception )
677  {
678  error()
679  << "GaudiException with tag=" << Exception.tag()
680  << " caught whilst finalizing tool '" << toolName << "'" << endmsg
681  << Exception << endmsg;
682  sc = StatusCode::FAILURE;
683  }
684  catch( const std::exception & Exception )
685  {
686  error()
687  << "Standard std::exception caught whilst finalizing tool '"
688  << toolName << "'" << endmsg << Exception.what() << endmsg;
689  sc = StatusCode::FAILURE;
690  }
691  catch (...)
692  {
693  error()
694  << "UNKNOWN Exception caught whilst finalizing tool '"
695  << toolName << "'" << endmsg;
696  sc = StatusCode::FAILURE;
697  }
698 
699  return sc;
700 
701 }
Define general base for Gaudi exception.
virtual StatusCode sysFinalize()=0
Finalization of the Tool.
virtual const std::string & name() const =0
Retrieve the name of the instance.
STL class.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
T what(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
virtual const std::string & tag() const
name tag for the exception, or exception type
STL class.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
std::vector< std::string > ToolSvc::getInstances ( const std::string toolType)
override

Get names of all tool instances of a given type.

Definition at line 351 of file ToolSvc.cpp.

353 {
354 
357  for(const auto& tool: m_instancesTools) {
358  if (tool->type() == toolType) tools.push_back( tool->name() );
359  }
360  return tools;
361 }
T push_back(T...args)
def lock(file)
Definition: locker.py:16
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
CallMutex m_mut
Definition: ToolSvc.h:111
std::vector< std::string > ToolSvc::getInstances ( ) const
override

Get names of all tool instances.

Definition at line 363 of file ToolSvc.cpp.

365 {
369  std::begin(tools), [](const IAlgTool* t) { return t->name(); } );
370  return tools;
371 }
T end(T...args)
virtual const std::string & name() const =0
Retrieve the name of the instance.
def lock(file)
Definition: locker.py:16
T size(T...args)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
T begin(T...args)
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
T transform(T...args)
CallMutex m_mut
Definition: ToolSvc.h:111
std::vector< IAlgTool * > ToolSvc::getTools ( ) const
override

Get pointers to all tool instances.

Definition at line 373 of file ToolSvc.cpp.

375 {
379 }
T end(T...args)
def lock(file)
Definition: locker.py:16
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
T begin(T...args)
CallMutex m_mut
Definition: ToolSvc.h:111
StatusCode ToolSvc::initialize ( )
override

Initialize the service.

Definition at line 52 of file ToolSvc.cpp.

54 {
55 
56  // initialize the Service Base class
58  if (UNLIKELY(status.isFailure()))
59  {
60  error() << "Unable to initialize the Service" << endmsg;
61  return status;
62  }
63 
64  // set my own (ToolSvc) properties via the jobOptionService
65  if (UNLIKELY(setProperties().isFailure())) {
66  error() << "Unable to set base properties" << endmsg;
67  return StatusCode::FAILURE;
68  }
69 
70  return status;
71 }
#define UNLIKELY(x)
Definition: Kernel.h:126
StatusCode initialize() override
Definition: Service.cpp:68
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
StatusCode setProperties()
Method for setting declared properties to the values specified for the job.
Definition: Service.cpp:363
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
unsigned long ToolSvc::minimumToolRefCount ( ) const
private

The minimum number of refCounts of all tools.

Definition at line 710 of file ToolSvc.cpp.

712 {
714  [](const IAlgTool* lhs, const IAlgTool* rhs) {
715  return lhs->refCount() < rhs->refCount();
716  } );
717  return i!=std::end(m_instancesTools) ? (*i)->refCount() : 0;
718 }
T end(T...args)
virtual unsigned long refCount() const =0
Current reference count.
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
T begin(T...args)
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
T min_element(T...args)
list i
Definition: ana.py:128
std::string ToolSvc::nameTool ( const std::string nameByUser,
const IInterface parent 
)

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

Definition at line 631 of file ToolSvc.cpp.

634 {
635 
636  if ( !parent ) { return this->name() + "." + toolname; } // RETURN
637 
638  // check that parent has a name!
639  auto named_parent = SmartIF<INamedInterface>( const_cast<IInterface*>(parent) );
640  if ( named_parent )
641  {
642  auto fullname = named_parent->name() + "." + toolname ;
643  return fullname ; // RETURN
644  }
645 
646  error() << "Private Tools only allowed for components implementing INamedInterface"
647  << endmsg;
648  //
649  return "." + toolname ;
650 }
tuple toolname
Definition: gaudirun.py:327
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:319
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Definition of the basic interface.
Definition: IInterface.h:234
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
void ToolSvc::registerObserver ( IToolSvc::Observer obs)
override

Definition at line 721 of file ToolSvc.cpp.

721  {
722 //------------------------------------------------------------------------------
724  if ( !obs )
725  throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
726  m_observers.push_back(obs);
727 }
Define general base for Gaudi exception.
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:108
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:319
T push_back(T...args)
def lock(file)
Definition: locker.py:16
CallMutex m_mut
Definition: ToolSvc.h:111
StatusCode ToolSvc::releaseTool ( IAlgTool tool)
override

Release tool.

Definition at line 381 of file ToolSvc.cpp.

383 {
386  // test if tool is in known list (protect trying to access a previously deleted tool)
389  tool ) ) {
390  unsigned long count = tool->refCount();
391  if ( count == 1 ) {
392  // finalize the tool
393 
395  // We are being called during ToolSvc::finalize()
396  // message format matches the one in ToolSvc::finalize()
397  debug() << " Performing finalization of " << tool->name()
398  << " (refCount " << count << ")" << endmsg;
399  // message format matches the one in ToolSvc::finalize()
400  debug() << " Performing deletion of " << tool->name() << endmsg;
401  } else {
402  debug() << "Performing finalization and deletion of " << tool->name() << endmsg;
403  }
404  sc = finalizeTool(tool);
405  // remove from known tools...
406  remove(m_instancesTools,tool);
407  }
408  tool->release();
409  }
410  return sc;
411 }
Gaudi::StateMachine::State m_targetState
Service state.
Definition: Service.h:313
T rend(T...args)
virtual const std::string & name() const =0
Retrieve the name of the instance.
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:663
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
virtual unsigned long refCount() const =0
Current reference count.
def lock(file)
Definition: locker.py:16
T count(T...args)
T find(T...args)
virtual unsigned long release()=0
Release Interface instance.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
CallMutex m_mut
Definition: ToolSvc.h:111
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
T rbegin(T...args)
StatusCode ToolSvc::retrieve ( const std::string 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 247 of file ToolSvc.cpp.

253 {
254  // check for tools, which by name are required to be public:
255  if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
256  // parent for PUBLIC tool is 'this', i.e. ToolSvc
257  return retrieve ( ba::erase_tail_copy(tooltype, s_PUBLIC.size()),
258  iid , tool , this , createIf ) ;
259  }
260 
261  // protect against empty type
262  if ( tooltype.empty() ) {
263  error() << "retrieve(): No Tool Type/Name given" << endmsg;
264  return StatusCode::FAILURE;
265  }
266  auto pos = tooltype.find('/');
267  if ( std::string::npos == pos ) {
268  return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );
269  }
270  return retrieve ( tooltype.substr( 0 , pos ),
271  tooltype.substr( pos + 1 ),
272  iid , tool , parent , createIf ) ;
273 }
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode retrieve(const std::string &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:247
StatusCode ToolSvc::retrieve ( const std::string tooltype,
const std::string 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 278 of file ToolSvc.cpp.

285 {
286  // check the applicability of another method:
287  // ignore the provided name if it is empty or the type contains a name
288  if( toolname.empty() || (std::string::npos != tooltype.find('/')) )
289  { return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
290 
291  // check for tools, which by name are required to be public:
292  if ( ba::ends_with( toolname, s_PUBLIC ) )
293  {
294  // parent for PUBLIC tool is this, i.e. ToolSvc
295  return retrieve ( tooltype , ba::erase_tail_copy(toolname, s_PUBLIC.size() ),
296  iid , tool , this , createIf ) ;
297  }
298 
300 
301  IAlgTool* itool = nullptr;
303 
304  tool = nullptr;
305 
306  // If parent is not specified it means it is the ToolSvc itself
307  if( !parent ) parent = this;
308  const std::string fullname = nameTool( toolname, parent );
309 
310  // Find tool in list of those already existing, and tell its
311  // interface that it has been used one more time
313  [&](const IAlgTool* i) {
314  return i->name() == fullname && i->parent() == parent;
315  });
316  if (it!=std::end(m_instancesTools)) {
317  ON_DEBUG debug() << "Retrieved tool " << toolname << " with parent " << parent << endmsg;
318  itool = *it;
319  }
320 
321  if ( !itool ) {
322  // Instances of this tool do not exist, create an instance if desired
323  // otherwise return failure
324  if( UNLIKELY(!createIf) ) {
325  warning() << "Tool " << toolname
326  << " not found and creation not requested" << endmsg;
327  return sc;
328  }
329  sc = create( tooltype, toolname, parent, itool );
330  if ( sc.isFailure() ) { return sc; }
331  }
332 
333  // Get the right interface of it
334  sc = itool->queryInterface( iid, pp_cast<void>(&tool) );
335  if( UNLIKELY(sc.isFailure()) ) {
336  error() << "Tool " << toolname
337  << " either does not implement the correct interface, or its version is incompatible"
338  << endmsg;
339  return sc;
340  }
341 
347  [&]( IToolSvc::Observer* obs ) { obs->onRetrieve(itool); } );
348  return sc;
349 }
#define UNLIKELY(x)
Definition: Kernel.h:126
T empty(T...args)
std::string nameTool(const std::string &nameByUser, const IInterface *parent)
Get Tool full name by combining nameByUser and "parent" part.
Definition: ToolSvc.cpp:631
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:244
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:414
T end(T...args)
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:108
virtual const std::string & name() const =0
Retrieve the name of the instance.
STL class.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
def lock(file)
Definition: locker.py:16
virtual const IInterface * parent() const =0
The parent of the concrete AlgTool.
T find(T...args)
T size(T...args)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
T begin(T...args)
virtual void onRetrieve(const IAlgTool *)
Definition: IToolSvc.h:248
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
#define ON_DEBUG
Definition: ToolSvc.cpp:20
CallMutex m_mut
Definition: ToolSvc.h:111
T for_each(T...args)
list i
Definition: ana.py:128
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
StatusCode retrieve(const std::string &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:247
StatusCode ToolSvc::start ( )
override

Definition at line 738 of file ToolSvc.cpp.

740 {
741 
742  ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
743 
744  bool fail(false);
745  for ( auto& iTool : m_instancesTools ) {
746  ON_VERBOSE verbose() << iTool->name() << "::start()" << endmsg;
747 
748  if (UNLIKELY(!iTool->sysStart().isSuccess())) {
749  fail = true;
750  error() << iTool->name() << " failed to start()" << endmsg;
751  }
752 
753  }
754 
755  if (UNLIKELY(fail)) {
756  error() << "One or more AlgTools failed to start()" << endmsg;
757  return StatusCode::FAILURE;
758  }
759  return StatusCode::SUCCESS;
760 }
#define UNLIKELY(x)
Definition: Kernel.h:126
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
#define ON_DEBUG
Definition: ToolSvc.cpp:20
#define ON_VERBOSE
Definition: ToolSvc.cpp:21
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode ToolSvc::stop ( )
override

Definition at line 764 of file ToolSvc.cpp.

766 {
767 
768  ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
769 
770  bool fail(false);
771  for ( auto& iTool : m_instancesTools ) {
772  ON_VERBOSE verbose() << iTool->name() << "::stop()" << endmsg;
773 
774  if (UNLIKELY(!iTool->sysStop().isSuccess())) {
775  fail = true;
776  error() << iTool->name() << " failed to stop()" << endmsg;
777  }
778 
779  }
780 
781  if (UNLIKELY(fail)) {
782  error() << "One or more AlgTools failed to stop()" << endmsg;
783  return StatusCode::FAILURE;
784  }
785  return StatusCode::SUCCESS;
786 }
#define UNLIKELY(x)
Definition: Kernel.h:126
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
#define ON_DEBUG
Definition: ToolSvc.cpp:20
#define ON_VERBOSE
Definition: ToolSvc.cpp:21
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
unsigned long ToolSvc::totalToolRefCount ( ) const
private

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

Definition at line 704 of file ToolSvc.cpp.

706 {
707  return totalRefCount( m_instancesTools );
708 }
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:103
void ToolSvc::unRegisterObserver ( IToolSvc::Observer obs)
override

Definition at line 730 of file ToolSvc.cpp.

730  {
732  auto i = std::find(m_observers.begin(),m_observers.end(),obs);
733  if (i!=m_observers.end()) m_observers.erase(i);
734 }
T end(T...args)
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:108
T erase(T...args)
def lock(file)
Definition: locker.py:16
T find(T...args)
T begin(T...args)
CallMutex m_mut
Definition: ToolSvc.h:111
list i
Definition: ana.py:128

Member Data Documentation

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

Common Tools.

Definition at line 103 of file ToolSvc.h.

CallMutex ToolSvc::m_mut
mutableprivate

Definition at line 111 of file ToolSvc.h.

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

Definition at line 108 of file ToolSvc.h.

IHistorySvc* ToolSvc::m_pHistorySvc = nullptr
private

Pointer to HistorySvc.

Definition at line 106 of file ToolSvc.h.


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