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