The Gaudi Framework  v29r0 (ff2e7097)
ToolSvc.cpp
Go to the documentation of this file.
1 // Include Files
2 #include "ToolSvc.h"
3 #include "GaudiKernel/AlgTool.h"
9 #include "GaudiKernel/Service.h"
10 #include "boost/algorithm/string/erase.hpp"
11 #include "boost/algorithm/string/predicate.hpp"
12 #include "boost/circular_buffer.hpp"
13 #include <algorithm>
14 #include <cassert>
15 #include <functional>
16 #include <map>
17 #include <numeric>
18 #include <string>
19 namespace ba = boost::algorithm;
20 
21 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
22 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
23 
24 namespace
25 {
26  //------------------------------------------------------------------------------
27  template <typename C>
28  unsigned long totalRefCount( const C& toolList )
29  //------------------------------------------------------------------------------
30  {
31  return std::accumulate( std::begin( toolList ), std::end( toolList ), 0ul,
32  [&]( unsigned long count, const IAlgTool* tool ) { return count + tool->refCount(); } );
33  }
34 
36  template <typename C>
37  void remove( C& c, typename C::const_reference i )
38  {
39  c.erase( std::remove( std::begin( c ), std::end( c ), i ), std::end( c ) );
40  }
41 }
42 
43 // Instantiation of a static factory class used by clients to create
44 // instances of this service
46 
47 //------------------------------------------------------------------------------
48 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc )
49  //------------------------------------------------------------------------------
50  : base_class( name, svc )
51 {
52 }
53 
55 {
56  // tell the remaining observers that we're gone, and forget about unregistering..
58  [&]( IToolSvc::Observer* obs ) { obs->setUnregister( {} ); } );
59 }
60 //------------------------------------------------------------------------------
62 //------------------------------------------------------------------------------
63 {
64 
65  // initialize the Service Base class
67  if ( UNLIKELY( status.isFailure() ) ) {
68  error() << "Unable to initialize the Service" << endmsg;
69  return status;
70  }
71 
72  // set my own (ToolSvc) properties via the jobOptionService
73  if ( UNLIKELY( setProperties().isFailure() ) ) {
74  error() << "Unable to set base properties" << endmsg;
75  return StatusCode::FAILURE;
76  }
77 
78  return status;
79 }
80 
81 //------------------------------------------------------------------------------
83 //------------------------------------------------------------------------------
84 {
85  // Finalize and delete all left-over tools. Normally all tools created with
86  // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
87  // Several cases need to be covered:
88  // 1) Simple dependencies: no circular dependencies between tools,
89  // and tools not using other tools
90  // 2) Tools-using-tools (but no circular dependencies)
91  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
92  // b) release() is called in the tool destructor (e.g. via ToolHandle)
93  // 3) Circular dependencies between tools
94  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
95  // b) release() is called in the tool destructor (e.g. via ToolHandle)
96  // 4) In addition to each of the above cases, refCounting of a particular tool
97  // might not have been done correctly in the code. Typically release()
98  // is not called, so we are left with a too high refCount.
99  // What to do with those, and how to avoid a crash while handling them...
100 
109  info() << "Removing all tools created by ToolSvc" << endmsg;
110 
111  // Print out list of tools
112  ON_DEBUG
113  {
114  auto& log = debug();
115  log << " Tool List : ";
116  for ( const auto& iTool : m_instancesTools ) {
117  log << iTool->name() << ":" << iTool->refCount() << " ";
118  }
119  log << endmsg;
120  }
121 
122  //
123  // first pass: Finalize all tools (but don't delete them)
124  //
137  boost::circular_buffer<IAlgTool*> finalizedTools( m_instancesTools.size() ); // list of tools that have been finalized
138  bool fail( false );
139  size_t toolCount = m_instancesTools.size();
140  unsigned long startRefCount = 0;
141  unsigned long endRefCount = totalToolRefCount();
142  unsigned long startMinRefCount = 0;
143  unsigned long endMinRefCount = minimumToolRefCount();
144  while ( toolCount > 0 && endRefCount > 0 && ( endRefCount != startRefCount || endMinRefCount != startMinRefCount ) ) {
145  ON_DEBUG if ( endMinRefCount != startMinRefCount )
146  {
147  debug() << toolCount << " tools left to finalize. Summed refCounts: " << endRefCount << endmsg;
148  debug() << "Will finalize tools with refCount <= " << endMinRefCount << endmsg;
149  }
150  startMinRefCount = endMinRefCount;
151  startRefCount = endRefCount;
152  unsigned long maxLoop = toolCount + 1;
153  while ( --maxLoop > 0 && !m_instancesTools.empty() ) {
154  IAlgTool* pTool = m_instancesTools.back();
155  // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
157  unsigned long count = pTool->refCount();
158  // cache tool name
159  const std::string& toolName = pTool->name();
160  if ( count <= startMinRefCount ) {
161  ON_DEBUG debug() << " Performing finalization of " << toolName << " (refCount " << count << ")" << endmsg;
162  // finalize of one tool may trigger a release of another tool
163  // pTool->sysFinalize().ignore();
164  if ( !finalizeTool( pTool ).isSuccess() ) {
165  warning() << " FAILURE finalizing " << toolName << endmsg;
166  fail = true;
167  }
168  // postpone deletion
169  finalizedTools.push_back( pTool );
170  } else {
171  // Place back at the front of the list to try again later
172  // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
173  ON_DEBUG debug() << " Delaying finalization of " << toolName << " (refCount " << count << ")" << endmsg;
175  }
176  } // end of inner loop
177  toolCount = m_instancesTools.size();
178  endRefCount = totalToolRefCount();
179  endMinRefCount = minimumToolRefCount();
180  }; // end of outer loop
181 
182  //
183  // Second pass: Delete all finalized tools
184  //
185  // Delete in the order of increasing number of refCounts.
186  // Loop over tools in the same order as the order in which they were finalized.
187  // All tools in the list of finalized tools are no longer in the instancesTools list.
188  // If a tool destructor calls releaseTool() on another tool, this will have no
189  // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
190  // If this 'other tool' is still in the instancesTools list, it may trigger finalization
191  // (in releaseTool()), deletion and removal from the instancesTools list.
192  // Therefore, the check on non-finalised tools should happen *after* the deletion
193  // of the finalized tools.
194  ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
195  auto maxLoop = totalRefCount( finalizedTools ) + 1;
196  while ( --maxLoop > 0 && !finalizedTools.empty() ) {
197  IAlgTool* pTool = finalizedTools.front();
198  finalizedTools.pop_front();
199  auto count = pTool->refCount();
200  if ( count == 1 ) {
201  ON_DEBUG debug() << " Performing deletion of " << pTool->name() << endmsg;
202  } else {
203  ON_VERBOSE verbose() << " Delaying deletion of " << pTool->name() << " (refCount " << count << ")" << endmsg;
204  // Move to the end when refCount still not zero
205  finalizedTools.push_back( pTool );
206  }
207  // do a forced release
208  pTool->release();
209  }
210 
211  // Error if by now not all tools are properly finalised
212  if ( !m_instancesTools.empty() ) {
213  error() << "Unable to finalize and delete the following tools : ";
214  for ( const auto& iTool : m_instancesTools ) {
215  error() << iTool->name() << ": " << iTool->refCount() << " ";
216  }
217  error() << endmsg;
218  }
219 
220  // by now, all tools should be deleted and removed.
221  if ( !finalizedTools.empty() ) {
222  error() << "Failed to delete the following " << finalizedTools.size()
223  << " finalized tools. Bug in ToolSvc::finalize()?: ";
224  for ( const auto& iTool : finalizedTools ) {
225  error() << iTool->name() << ": " << iTool->refCount() << " ";
226  }
227  error() << endmsg;
228  }
229 
230  if ( m_pHistorySvc ) m_pHistorySvc->release();
231 
232  // Finalize this specific service
233  return ( Service::finalize().isSuccess() && !fail ) ? StatusCode::SUCCESS : StatusCode::FAILURE;
234 }
235 
236 // ===================================================================================
240 // ===================================================================================
241 namespace
242 {
243  static const std::string s_PUBLIC = ":PUBLIC";
244 }
245 
246 //------------------------------------------------------------------------------
247 StatusCode ToolSvc::retrieve( const std::string& tooltype, const InterfaceID& iid, IAlgTool*& tool,
248  const IInterface* parent, bool createIf )
249 //------------------------------------------------------------------------------
250 {
251  // check for tools, which by name are required to be public:
252  if ( ba::ends_with( tooltype, s_PUBLIC ) ) {
253  // parent for PUBLIC tool is 'this', i.e. ToolSvc
254  return retrieve( ba::erase_tail_copy( tooltype, s_PUBLIC.size() ), iid, tool, this, createIf );
255  }
256 
257  // protect against empty type
258  if ( tooltype.empty() ) {
259  error() << "retrieve(): No Tool Type/Name given" << endmsg;
260  return StatusCode::FAILURE;
261  }
262  auto pos = tooltype.find( '/' );
263  if ( std::string::npos == pos ) {
264  return retrieve( tooltype, tooltype, iid, tool, parent, createIf );
265  }
266  return retrieve( tooltype.substr( 0, pos ), tooltype.substr( pos + 1 ), iid, tool, parent, createIf );
267 }
268 
269 // ===================================================================================
270 
271 //------------------------------------------------------------------------------
273  IAlgTool*& tool, const IInterface* parent, bool createIf )
274 //------------------------------------------------------------------------------
275 {
276  // check the applicability of another method:
277  // ignore the provided name if it is empty or the type contains a name
278  if ( toolname.empty() || ( std::string::npos != tooltype.find( '/' ) ) ) {
279  return retrieve( tooltype, iid, tool, parent, createIf );
280  }
281 
282  // check for tools, which by name are required to be public:
283  if ( ba::ends_with( toolname, s_PUBLIC ) ) {
284  // parent for PUBLIC tool is this, i.e. ToolSvc
285  return retrieve( tooltype, ba::erase_tail_copy( toolname, s_PUBLIC.size() ), iid, tool, this, createIf );
286  }
287 
289 
290  IAlgTool* itool = nullptr;
292 
293  tool = nullptr;
294 
295  // If parent is not specified it means it is the ToolSvc itself
296  if ( !parent ) parent = this;
297  const std::string fullname = nameTool( toolname, parent );
298 
299  // Find tool in list of those already existing, and tell its
300  // interface that it has been used one more time
302  [&]( const IAlgTool* i ) { return i->name() == fullname && i->parent() == parent; } );
303  if ( it != std::end( m_instancesTools ) ) {
304  ON_DEBUG debug() << "Retrieved tool " << toolname << " with parent " << parent << endmsg;
305  itool = *it;
306  }
307 
308  if ( !itool ) {
309  // Instances of this tool do not exist, create an instance if desired
310  // otherwise return failure
311  if ( UNLIKELY( !createIf ) ) {
312  warning() << "Tool " << toolname << " not found and creation not requested" << endmsg;
313  return sc;
314  }
315  sc = create( tooltype, toolname, parent, itool );
316  if ( sc.isFailure() ) {
317  return sc;
318  }
319  }
320 
321  // Get the right interface of it
322  sc = itool->queryInterface( iid, pp_cast<void>( &tool ) );
323  if ( UNLIKELY( sc.isFailure() ) ) {
324  error() << "Tool " << toolname << " either does not implement the correct interface, or its version is incompatible"
325  << endmsg;
326  return sc;
327  }
328 
333  [&]( IToolSvc::Observer* obs ) { obs->onRetrieve( itool ); } );
334  return sc;
335 }
336 //------------------------------------------------------------------------------
338 //------------------------------------------------------------------------------
339 {
340 
343  for ( const auto& tool : m_instancesTools ) {
344  if ( tool->type() == toolType ) tools.push_back( tool->name() );
345  }
346  return tools;
347 }
348 //------------------------------------------------------------------------------
350 //------------------------------------------------------------------------------
351 {
355  []( const IAlgTool* t ) { return t->name(); } );
356  return tools;
357 }
358 //------------------------------------------------------------------------------
360 //------------------------------------------------------------------------------
361 {
364 }
365 //------------------------------------------------------------------------------
367 //------------------------------------------------------------------------------
368 {
371  // test if tool is in known list (protect trying to access a previously deleted tool)
373  unsigned long count = tool->refCount();
374  if ( count == 1 ) {
375  // finalize the tool
376 
378  // We are being called during ToolSvc::finalize()
379  // message format matches the one in ToolSvc::finalize()
380  debug() << " Performing finalization of " << tool->name() << " (refCount " << count << ")" << endmsg;
381  // message format matches the one in ToolSvc::finalize()
382  debug() << " Performing deletion of " << tool->name() << endmsg;
383  } else {
384  debug() << "Performing finalization and deletion of " << tool->name() << endmsg;
385  }
386  sc = finalizeTool( tool );
387  // remove from known tools...
388  remove( m_instancesTools, tool );
389  }
390  tool->release();
391  }
392  return sc;
393 }
394 
395 //------------------------------------------------------------------------------
396 StatusCode ToolSvc::create( const std::string& tooltype, const IInterface* parent, IAlgTool*& tool )
397 //------------------------------------------------------------------------------
398 {
399  const std::string& toolname = tooltype;
400  return create( tooltype, toolname, parent, tool );
401 }
402 
403 namespace
404 {
407  template <typename T>
408  class ToolCreateGuard
409  {
411  T& m_tools;
414 
415  public:
416  explicit ToolCreateGuard( T& tools ) : m_tools( tools ) {}
417  // we don't get a move constructor by default because we
418  // have a non-trivial destructor... However, the default
419  // one is just fine...
420  ToolCreateGuard( ToolCreateGuard&& ) noexcept = default;
422  void create( const std::string& tooltype, const std::string& fullname, const IInterface* parent )
423  {
424  // remove previous content
425  if ( m_tool ) remove( m_tools, m_tool.get() );
426  m_tool.reset( AlgTool::Factory::create( tooltype, tooltype, fullname, parent ) );
427  // set new content
428  if ( m_tool ) m_tools.push_back( m_tool.get() );
429  }
431  IAlgTool* get() { return m_tool.get(); }
432  IAlgTool* operator->() const
433  {
434  assert( m_tool );
435  return m_tool.get();
436  }
438  IAlgTool* release() { return m_tool.release(); }
440  ~ToolCreateGuard()
441  {
442  if ( m_tool ) remove( m_tools, m_tool.get() );
443  }
444  };
445 
446  template <typename C>
447  ToolCreateGuard<C> make_toolCreateGuard( C& c )
448  {
449  return ToolCreateGuard<C>{c};
450  }
451 }
452 
453 //------------------------------------------------------------------------------
461 StatusCode ToolSvc::create( const std::string& tooltype, const std::string& toolname, const IInterface* parent,
462  IAlgTool*& tool )
463 //------------------------------------------------------------------------------
464 {
465 
467  // protect against empty type
468  if ( UNLIKELY( tooltype.empty() ) ) {
469  error() << "create(): No Tool Type given" << endmsg;
470  return StatusCode::FAILURE;
471  }
472 
473  // If parent has not been specified, assume it is the ToolSvc
474  if ( !parent ) parent = this;
475 
476  tool = nullptr;
477  // Automatically deletes the tool if not explicitly kept (i.e. on success).
478  // The tool is removed from the list of known tools too.
479  auto toolguard = make_toolCreateGuard( m_instancesTools );
480 
481  // Check if the tool already exist : this could happen with clones
482  std::string fullname = nameTool( toolname, parent );
483  if ( UNLIKELY( existsTool( fullname ) ) ) {
484  // Now check if the parent is the same. This allows for clones
485  for ( IAlgTool* iAlgTool : m_instancesTools ) {
486  if ( iAlgTool->name() == toolname && iAlgTool->parent() == parent ) {
487  // The tool exist with this name, type and parent: this is bad!
488  // This excludes the possibility of cloning public tools intrinsecally
489  error() << "Tool " << fullname << " already exists with the same parent" << endmsg;
490  if ( parent == this )
491  error() << "... In addition, the parent is the ToolSvc: public tools cannot be cloned!" << endmsg;
492 
493  return StatusCode::FAILURE;
494  }
495  }
496  ON_DEBUG debug() << "Creating clone of " << fullname << endmsg;
497  }
498  // instantiate the tool using the factory
499  try {
500  toolguard.create( tooltype, fullname, parent );
501  if ( UNLIKELY( !toolguard.get() ) ) {
502  error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
503  return StatusCode::FAILURE;
504  }
505  } catch ( const GaudiException& Exception ) {
506  // (1) perform the printout of message
507  fatal() << "Exception with tag=" << Exception.tag() << " is caught whilst instantiating tool '" << tooltype << "'"
508  << endmsg;
509  // (2) print the exception itself
510  // (NB! - GaudiException is a linked list of all "previous exceptions")
511  fatal() << Exception << endmsg;
512  return StatusCode::FAILURE;
513  } catch ( const std::exception& Exception ) {
514  // (1) perform the printout of message
515  fatal() << "Standard std::exception is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
516  // (2) print the exception itself
517  // (NB! - GaudiException is a linked list of all "previous exceptions")
518  fatal() << Exception.what() << endmsg;
519  return StatusCode::FAILURE;
520  } catch ( ... ) {
521  // (1) perform the printout
522  fatal() << "UNKNOWN Exception is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
523  return StatusCode::FAILURE;
524  }
525  ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
526 
527  // Since only AlgTool has the setProperties() method it is necessary to cast
528  // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
529  // service
530  AlgTool* mytool = dynamic_cast<AlgTool*>( toolguard.get() );
531  if ( mytool ) {
532  StatusCode sc = mytool->setProperties();
533  if ( UNLIKELY( sc.isFailure() ) ) {
534  error() << "Error setting properties for tool '" << fullname << "'" << endmsg;
535  return sc;
536  }
537  }
538 
539  // Initialize the Tool
540  StatusCode sc( StatusCode::FAILURE, true );
541  try {
542  sc = toolguard->sysInitialize();
543  }
544  // Catch any exceptions
545  catch ( const GaudiException& Exception ) {
546  error() << "GaudiException with tag=" << Exception.tag() << " caught whilst initializing tool '" << fullname << "'"
547  << endmsg << Exception << endmsg;
548  return StatusCode::FAILURE;
549  } catch ( const std::exception& Exception ) {
550  error() << "Standard std::exception caught whilst initializing tool '" << fullname << "'" << endmsg
551  << Exception.what() << endmsg;
552  return StatusCode::FAILURE;
553  } catch ( ... ) {
554  error() << "UNKNOWN Exception caught whilst initializing tool '" << fullname << "'" << endmsg;
555  return StatusCode::FAILURE;
556  }
557 
558  // Status of tool initialization
559  if ( UNLIKELY( sc.isFailure() ) ) {
560  error() << "Error initializing tool '" << fullname << "'" << endmsg;
561  return sc;
562  }
563 
564  // Start the tool if we are running.
566  sc = toolguard->sysStart();
567 
568  if ( UNLIKELY( sc.isFailure() ) ) {
569  error() << "Error starting tool '" << fullname << "'" << endmsg;
570  return sc;
571  }
572  }
573 
574  // The tool has been successfully created and initialized,
575  // so we inform the guard that it can release it
576  tool = toolguard.release();
577 
581  std::for_each( m_observers.begin(), m_observers.end(), [&]( IToolSvc::Observer* obs ) { obs->onCreate( tool ); } );
582  // TODO: replace by generic callback
583  // Register the tool with the HistorySvc
584  if ( m_pHistorySvc || service( "HistorySvc", m_pHistorySvc, false ).isSuccess() ) {
586  }
587  return StatusCode::SUCCESS;
588 }
589 
590 //------------------------------------------------------------------------------
592 //------------------------------------------------------------------------------
593 {
594 
595  if ( !parent ) {
596  return this->name() + "." + toolname;
597  } // RETURN
598 
599  // check that parent has a name!
600  auto named_parent = SmartIF<INamedInterface>( const_cast<IInterface*>( parent ) );
601  if ( named_parent ) {
602  auto fullname = named_parent->name() + "." + toolname;
603  return fullname; // RETURN
604  }
605 
606  error() << "Private Tools only allowed for components implementing INamedInterface" << endmsg;
607  //
608  return "." + toolname;
609 }
610 
611 //------------------------------------------------------------------------------
612 bool ToolSvc::existsTool( const std::string& fullname ) const
613 //------------------------------------------------------------------------------
614 {
617  [&]( const IAlgTool* tool ) { return tool->name() == fullname; } );
618  return i != std::end( m_instancesTools );
619 }
620 
621 //------------------------------------------------------------------------------
623 //------------------------------------------------------------------------------
624 {
625 
626  // Cache tool name in case of errors
627  const std::string toolName = itool->name();
628  StatusCode sc;
629 
630  // Finalise the tool inside a try block
631  try {
632  sc = itool->sysFinalize();
633  }
634  // Catch any exceptions
635  catch ( const GaudiException& Exception ) {
636  error() << "GaudiException with tag=" << Exception.tag() << " caught whilst finalizing tool '" << toolName << "'"
637  << endmsg << Exception << endmsg;
638  sc = StatusCode::FAILURE;
639  } catch ( const std::exception& Exception ) {
640  error() << "Standard std::exception caught whilst finalizing tool '" << toolName << "'" << endmsg
641  << Exception.what() << endmsg;
642  sc = StatusCode::FAILURE;
643  } catch ( ... ) {
644  error() << "UNKNOWN Exception caught whilst finalizing tool '" << toolName << "'" << endmsg;
645  sc = StatusCode::FAILURE;
646  }
647 
648  return sc;
649 }
650 
651 //------------------------------------------------------------------------------
652 unsigned long ToolSvc::totalToolRefCount() const
653 //------------------------------------------------------------------------------
654 {
655  return totalRefCount( m_instancesTools );
656 }
657 //------------------------------------------------------------------------------
658 unsigned long ToolSvc::minimumToolRefCount() const
659 //------------------------------------------------------------------------------
660 {
661  auto i =
663  []( const IAlgTool* lhs, const IAlgTool* rhs ) { return lhs->refCount() < rhs->refCount(); } );
664  return i != std::end( m_instancesTools ) ? ( *i )->refCount() : 0;
665 }
666 
667 //------------------------------------------------------------------------------
669 {
670  //------------------------------------------------------------------------------
671  if ( !obs ) throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
672 
674  obs->setUnregister( [this, obs]() {
676  auto i = std::find( m_observers.begin(), m_observers.end(), obs );
677  if ( i != m_observers.end() ) m_observers.erase( i );
678  } );
679  m_observers.push_back( obs );
680 }
681 
682 //------------------------------------------------------------------------------
684 //------------------------------------------------------------------------------
685 {
686 
687  ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
688 
689  bool fail( false );
690  for ( auto& iTool : m_instancesTools ) {
691  ON_VERBOSE verbose() << iTool->name() << "::start()" << endmsg;
692 
693  if ( UNLIKELY( !iTool->sysStart().isSuccess() ) ) {
694  fail = true;
695  error() << iTool->name() << " failed to start()" << endmsg;
696  }
697  }
698 
699  if ( UNLIKELY( fail ) ) {
700  error() << "One or more AlgTools failed to start()" << endmsg;
701  return StatusCode::FAILURE;
702  }
703  return StatusCode::SUCCESS;
704 }
705 
706 //------------------------------------------------------------------------------
708 //------------------------------------------------------------------------------
709 {
710 
711  ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
712 
713  bool fail( false );
714  for ( auto& iTool : m_instancesTools ) {
715  ON_VERBOSE verbose() << iTool->name() << "::stop()" << endmsg;
716 
717  if ( UNLIKELY( !iTool->sysStop().isSuccess() ) ) {
718  fail = true;
719  error() << iTool->name() << " failed to stop()" << endmsg;
720  }
721  }
722 
723  if ( UNLIKELY( fail ) ) {
724  error() << "One or more AlgTools failed to stop()" << endmsg;
725  return StatusCode::FAILURE;
726  }
727  return StatusCode::SUCCESS;
728 }
IHistorySvc * m_pHistorySvc
Pointer to HistorySvc.
Definition: ToolSvc.h:99
#define UNLIKELY(x)
Definition: Kernel.h:128
Gaudi::StateMachine::State m_targetState
Service state.
Definition: Service.h:162
StatusCode initialize() override
Definition: Service.cpp:64
T empty(T...args)
Define general base for Gaudi exception.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
StatusCode releaseTool(IAlgTool *tool) override
Release tool.
Definition: ToolSvc.cpp:366
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:289
Gaudi::StateMachine::State m_state
Service state.
Definition: Service.h:160
StatusCode finalize() override
Definition: Service.cpp:174
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
std::string nameTool(const std::string &nameByUser, const IInterface *parent)
Get Tool full name by combining nameByUser and "parent" part.
Definition: ToolSvc.cpp:591
T rend(T...args)
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:223
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
unsigned long minimumToolRefCount() const
The minimum number of refCounts of all tools.
Definition: ToolSvc.cpp:658
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:396
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
STL namespace.
std::vector< std::string > getInstances() const override
Get names of all tool instances.
Definition: ToolSvc.cpp:349
void registerObserver(IToolSvc::Observer *obs) override
Definition: ToolSvc.cpp:668
T end(T...args)
T remove(T...args)
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:101
bool existsTool(const std::string &toolname) const
Check if the tool instance exists.
Definition: ToolSvc.cpp:612
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
StatusCode initialize() override
Initialize the service.
Definition: ToolSvc.cpp:61
This service manages tools.
Definition: ToolSvc.h:24
T release(T...args)
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:33
StatusCode setProperties()
Method for setting declared properties to the values specified in the jobOptions via the job option s...
Definition: AlgTool.cpp:117
STL class.
StatusCode start() override
Definition: ToolSvc.cpp:683
virtual void onCreate(const IAlgTool *)
Definition: IToolSvc.h:232
T push_back(T...args)
Interface ID class.
Definition: IInterface.h:29
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:652
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:622
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
T what(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
virtual StatusCode registerAlgTool(const IAlgTool &)=0
~ToolSvc() override
Destructor.
Definition: ToolSvc.cpp:54
Definition of the basic interface.
Definition: IInterface.h:277
T erase(T...args)
T pop_back(T...args)
virtual const std::string & tag() const
name tag for the exception, or exception type
T reset(T...args)
STL class.
StatusCode setProperties()
Method for setting declared properties to the values specified for the job.
Definition: Service.cpp:295
T get(T...args)
T insert(T...args)
T find(T...args)
T size(T...args)
void setUnregister(std::function< void()> unregister)
Definition: IToolSvc.h:230
virtual unsigned long release()=0
Release Interface instance.
STL class.
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:96
T begin(T...args)
virtual void onRetrieve(const IAlgTool *)
Definition: IToolSvc.h:233
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:48
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
#define ON_DEBUG
Definition: ToolSvc.cpp:21
StatusCode finalize() override
Finalize the service.
Definition: ToolSvc.cpp:82
T back(T...args)
T substr(T...args)
std::vector< IAlgTool * > getTools() const override
Get pointers to all tool instances.
Definition: ToolSvc.cpp:359
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn&#39;t already exist.
Definition: Service.h:85
T transform(T...args)
virtual unsigned long refCount() const =0
Current reference count.
T accumulate(T...args)
void ignore() const
Definition: StatusCode.h:109
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
CallMutex m_mut
Definition: ToolSvc.h:104
T min_element(T...args)
T for_each(T...args)
virtual const IInterface * parent() const =0
The parent of the concrete AlgTool.
StatusCode stop() override
Definition: ToolSvc.cpp:707
#define ON_VERBOSE
Definition: ToolSvc.cpp:22
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
virtual const std::string & name() const =0
Retrieve the name of the instance.
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
T rbegin(T...args)