All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ToolSvc.cpp
Go to the documentation of this file.
1 // Include Files
2 #include "GaudiKernel/MsgStream.h"
3 #include "GaudiKernel/Service.h"
4 #include "GaudiKernel/ISvcLocator.h"
5 #include "GaudiKernel/IAlgorithm.h"
6 #include "GaudiKernel/GaudiException.h"
7 #include "GaudiKernel/AlgTool.h"
8 #include "GaudiKernel/IHistorySvc.h"
9 #include "ToolSvc.h"
10 #include <algorithm>
11 #include <map>
12 #include <string>
13 #include <cassert>
14 #include <functional>
15 #include "boost/circular_buffer.hpp"
16 #include "boost/algorithm/string/predicate.hpp"
17 #include "boost/algorithm/string/erase.hpp"
18 namespace ba = boost::algorithm;
19 
20 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
21 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
22 
23 namespace {
24 //------------------------------------------------------------------------------
25 template <typename C>
26 unsigned long totalRefCount( const C& toolList )
27 //------------------------------------------------------------------------------
28 {
29  return std::accumulate( std::begin(toolList), std::end(toolList), 0ul,
30  [&](unsigned long count, const IAlgTool* tool ) {
31  return count + tool->refCount();
32  });
33 }
34 
36 template <typename C> void remove(C& c, typename C::const_reference i) {
37  c.erase( std::remove(std::begin(c),std::end(c),i), std::end(c) );
38 }
39 
40 }
41 
42 // Instantiation of a static factory class used by clients to create
43 // instances of this service
45 
46 //------------------------------------------------------------------------------
47 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc )
48  //------------------------------------------------------------------------------
49  : base_class( name, svc) { }
50 
51 //------------------------------------------------------------------------------
53  //------------------------------------------------------------------------------
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 }
72 
73 //------------------------------------------------------------------------------
75  //------------------------------------------------------------------------------
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  MsgStream &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 }
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 ,
248  const InterfaceID& iid ,
249  IAlgTool*& tool ,
250  const IInterface* parent ,
251  bool createIf )
252 //------------------------------------------------------------------------------
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 }
274 
275 // ===================================================================================
276 
277 //------------------------------------------------------------------------------
278 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
279  const std::string& toolname ,
280  const InterfaceID& iid ,
281  IAlgTool*& tool ,
282  const IInterface* parent ,
283  bool createIf )
284  //------------------------------------------------------------------------------
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 
299  IAlgTool* itool = nullptr;
301 
302  tool = nullptr;
303 
304  // If parent is not specified it means it is the ToolSvc itself
305  if( !parent ) parent = this;
306  const std::string fullname = nameTool( toolname, parent );
307 
308  // Find tool in list of those already existing, and tell its
309  // interface that it has been used one more time
310  auto it = std::find_if( std::begin(m_instancesTools), std::end(m_instancesTools),
311  [&](const IAlgTool* i) {
312  return i->name() == fullname && i->parent() == parent;
313  });
314  if (it!=std::end(m_instancesTools)) {
315  ON_DEBUG debug() << "Retrieved tool " << toolname << " with parent " << parent << endmsg;
316  itool = *it;
317  }
318 
319  if ( !itool ) {
320  // Instances of this tool do not exist, create an instance if desired
321  // otherwise return failure
322  if( UNLIKELY(!createIf) ) {
323  warning() << "Tool " << toolname
324  << " not found and creation not requested" << endmsg;
325  return sc;
326  }
327  sc = create( tooltype, toolname, parent, itool );
328  if ( sc.isFailure() ) { return sc; }
329  }
330 
331  // Get the right interface of it
332  sc = itool->queryInterface( iid, pp_cast<void>(&tool) );
333  if( UNLIKELY(sc.isFailure()) ) {
334  error() << "Tool " << toolname
335  << " either does not implement the correct interface, or its version is incompatible"
336  << endmsg;
337  return sc;
338  }
339 
343  std::for_each( std::begin(m_observers),
345  [&]( IToolSvc::Observer* obs ) { obs->onRetrieve(itool); } );
346  return sc;
347 }
348 //------------------------------------------------------------------------------
349 std::vector<std::string> ToolSvc::getInstances( const std::string& toolType )
350 //------------------------------------------------------------------------------
351 {
352  std::vector<std::string> tools;
353  for(const auto& tool: m_instancesTools) {
354  if (tool->type() == toolType) tools.push_back( tool->name() );
355  }
356  return tools;
357 }
358 //------------------------------------------------------------------------------
359 std::vector<std::string> ToolSvc::getInstances() const
360 //------------------------------------------------------------------------------
361 {
362  std::vector<std::string> tools{m_instancesTools.size()};
364  std::begin(tools), [](const IAlgTool* t) { return t->name(); } );
365  return tools;
366 }
367 //------------------------------------------------------------------------------
368 std::vector<IAlgTool*> ToolSvc::getTools() const
369 //------------------------------------------------------------------------------
370 {
371  return m_instancesTools;
372 }
373 //------------------------------------------------------------------------------
375  //------------------------------------------------------------------------------
376 {
378  // test if tool is in known list (protect trying to access a previously deleted tool)
379  if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(),
380  m_instancesTools.rend(),
381  tool ) ) {
382  unsigned long count = tool->refCount();
383  if ( count == 1 ) {
384  MsgStream log( msgSvc(), name() );
385  // finalize the tool
386 
387  if ( Gaudi::StateMachine::OFFLINE == m_targetState ) {
388  // We are being called during ToolSvc::finalize()
389  // message format matches the one in ToolSvc::finalize()
390  log << MSG::DEBUG << " Performing finalization of " << tool->name()
391  << " (refCount " << count << ")" << endmsg;
392  // message format matches the one in ToolSvc::finalize()
393  log << MSG::DEBUG << " Performing deletion of " << tool->name() << endmsg;
394  } else {
395  log << MSG::DEBUG << "Performing finalization and deletion of " << tool->name() << endmsg;
396  }
397  sc = finalizeTool(tool);
398  // remove from known tools...
399  remove(m_instancesTools,tool);
400  }
401  tool->release();
402  }
403  return sc;
404 }
405 
406 //------------------------------------------------------------------------------
407 StatusCode ToolSvc::create(const std::string& tooltype,
408  const IInterface* parent,
409  IAlgTool*& tool)
410  //------------------------------------------------------------------------------
411 {
412  const std::string & toolname = tooltype;
413  return create( tooltype, toolname, parent, tool);
414 }
415 
416 namespace {
419 template <typename T>
420 class ToolCreateGuard {
422  T& m_tools;
424  std::unique_ptr<IAlgTool> m_tool;
425 
426 public:
427  explicit ToolCreateGuard(T& tools): m_tools(tools) {}
428  // we don't get a move constructor by default because we
429  // have a non-trivial destructor... However, the default
430  // one is just fine...
431  ToolCreateGuard(ToolCreateGuard&&) noexcept = default;
433  void create( const std::string& tooltype, const std::string& fullname, const IInterface* parent ) {
434  // remove previous content
435  if (m_tool) remove(m_tools,m_tool.get());
436  m_tool.reset(AlgTool::Factory::create(tooltype, tooltype, fullname, parent)) ;
437  // set new content
438  if (m_tool) m_tools.push_back(m_tool.get());
439  }
441  IAlgTool* get() {
442  return m_tool.get();
443  }
444  IAlgTool* operator->() const {
445  assert(m_tool);
446  return m_tool.get();
447  }
449  IAlgTool* release() {
450  return m_tool.release();
451  }
453  ~ToolCreateGuard(){
454  if (m_tool) remove(m_tools,m_tool.get());
455  }
456 };
457 
458 template <typename C>
459 ToolCreateGuard<C> make_toolCreateGuard(C& c) {
460  return ToolCreateGuard<C>{ c };
461 }
462 }
463 
464 //------------------------------------------------------------------------------
472 StatusCode ToolSvc::create(const std::string& tooltype,
473  const std::string& toolname,
474  const IInterface* parent,
475  IAlgTool*& tool)
476  //------------------------------------------------------------------------------
477 {
478 
479  // protect against empty type
480  if ( UNLIKELY(tooltype.empty()) ) {
481  error() << "create(): No Tool Type given" << endmsg;
482  return StatusCode::FAILURE;
483  }
484 
485  // If parent has not been specified, assume it is the ToolSvc
486  if ( !parent ) parent = this;
487 
488  tool = nullptr;
489  // Automatically deletes the tool if not explicitly kept (i.e. on success).
490  // The tool is removed from the list of known tools too.
491  auto toolguard = make_toolCreateGuard(m_instancesTools);
492 
493  // Check if the tool already exist : this could happen with clones
494  std::string fullname = nameTool(toolname, parent);
495  if( UNLIKELY(existsTool(fullname)) ) {
496  // Now check if the parent is the same. This allows for clones
498  if ( iAlgTool->name() == toolname && iAlgTool->parent() == parent){
499  // The tool exist with this name, type and parent: this is bad!
500  // This excludes the possibility of cloning public tools intrinsecally
501  error() << "Tool " << fullname << " already exists with the same parent" << endmsg;
502  if (parent == this)
503  error() << "... In addition, the parent is the ToolSvc: public tools cannot be cloned!" << endmsg;
504 
505  return StatusCode::FAILURE;
506  }
507  }
508  ON_DEBUG debug() << "Creating clone of " << fullname << endmsg;
509  }
510  // instantiate the tool using the factory
511  try {
512  toolguard.create( tooltype, fullname, parent );
513  if ( UNLIKELY(! toolguard.get()) ){
514  error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
515  return StatusCode::FAILURE;
516  }
517  }
518  catch ( const GaudiException& Exception ) {
519  // (1) perform the printout of message
520  fatal() << "Exception with tag=" << Exception.tag()
521  << " is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
522  // (2) print the exception itself
523  // (NB! - GaudiException is a linked list of all "previous exceptions")
524  fatal() << Exception << endmsg;
525  return StatusCode::FAILURE;
526  }
527  catch( const std::exception& Exception ) {
528  // (1) perform the printout of message
529  fatal() << "Standard std::exception is caught whilst instantiating tool '"
530  << tooltype << "'" << endmsg;
531  // (2) print the exception itself
532  // (NB! - GaudiException is a linked list of all "previous exceptions")
533  fatal() << Exception.what() << endmsg;
534  return StatusCode::FAILURE;
535  }
536  catch(...) {
537  // (1) perform the printout
538  fatal() << "UNKNOWN Exception is caught whilst instantiating tool '"
539  << tooltype << "'" << endmsg;
540  return StatusCode::FAILURE;
541  }
542  ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
543 
544  // Since only AlgTool has the setProperties() method it is necessary to cast
545  // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
546  // service
547  AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get());
548  if ( mytool ) {
549  StatusCode sc = mytool->setProperties();
550  if ( UNLIKELY(sc.isFailure()) ) {
551  error() << "Error setting properties for tool '"
552  << fullname << "'" << endmsg;
553  return sc;
554  }
555  }
556 
557  // Initialize the Tool
559  try {
560  sc = toolguard->sysInitialize();
561  }
562  // Catch any exceptions
563  catch ( const GaudiException & Exception )
564  {
565  error()
566  << "GaudiException with tag=" << Exception.tag()
567  << " caught whilst initializing tool '" << fullname << "'" << endmsg
568  << Exception << endmsg;
569  return StatusCode::FAILURE;
570  }
571  catch( const std::exception & Exception )
572  {
573  error()
574  << "Standard std::exception caught whilst initializing tool '"
575  << fullname << "'" << endmsg << Exception.what() << endmsg;
576  return StatusCode::FAILURE;
577  }
578  catch (...)
579  {
580  error()
581  << "UNKNOWN Exception caught whilst initializing tool '"
582  << fullname << "'" << endmsg;
583  return StatusCode::FAILURE;
584  }
585 
586  // Status of tool initialization
587  if ( UNLIKELY(sc.isFailure()) ) {
588  error() << "Error initializing tool '" << fullname << "'" << endmsg;
589  return sc;
590  }
591 
592  // Start the tool if we are running.
593  if (m_state == Gaudi::StateMachine::RUNNING) {
594  sc = toolguard->sysStart();
595 
596  if (UNLIKELY(sc.isFailure())) {
597  error() << "Error starting tool '" << fullname << "'" << endmsg;
598  return sc;
599  }
600  }
601 
602 
603  // The tool has been successfully created and initialized,
604  // so we inform the guard that it can release it
605  tool = toolguard.release();
606 
610  std::for_each( m_observers.begin(),
611  m_observers.end(),
612  [&](IToolSvc::Observer* obs) { obs->onCreate(tool); } );
613  // TODO: replace by generic callback
614  // Register the tool with the HistorySvc
615  if (m_pHistorySvc || service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
617  }
618  return StatusCode::SUCCESS;
619 
620 }
621 
622 //------------------------------------------------------------------------------
623 std::string ToolSvc::nameTool( const std::string& toolname,
624  const IInterface* parent )
625  //------------------------------------------------------------------------------
626 {
627 
628  if ( !parent ) { return this->name() + "." + toolname; } // RETURN
629 
630  // check that parent has a name!
631  auto named_parent = SmartIF<INamedInterface>( const_cast<IInterface*>(parent) );
632  if ( named_parent )
633  {
634  auto fullname = named_parent->name() + "." + toolname ;
635  return fullname ; // RETURN
636  }
637 
638  MsgStream log ( msgSvc(), name() );
639  log << MSG::ERROR
640  << "Private Tools only allowed for components implementing INamedInterface"
641  << endmsg;
642  //
643  return "." + toolname ;
644 }
645 
646 //------------------------------------------------------------------------------
647 bool ToolSvc::existsTool( const std::string& fullname) const
648  //------------------------------------------------------------------------------
649 {
650  auto i = std::find_if( std::begin(m_instancesTools), std::end(m_instancesTools),
651  [&](const IAlgTool* tool) { return tool->name() == fullname; } );
652  return i != std::end(m_instancesTools);
653 }
654 
655 //------------------------------------------------------------------------------
657  //------------------------------------------------------------------------------
658 {
659 
660  // Cache tool name in case of errors
661  const std::string toolName = itool->name();
662  StatusCode sc;
663 
664  // Finalise the tool inside a try block
665  try {
666  sc = itool->sysFinalize();
667  }
668  // Catch any exceptions
669  catch ( const GaudiException & Exception )
670  {
671  error()
672  << "GaudiException with tag=" << Exception.tag()
673  << " caught whilst finalizing tool '" << toolName << "'" << endmsg
674  << Exception << endmsg;
675  sc = StatusCode::FAILURE;
676  }
677  catch( const std::exception & Exception )
678  {
679  error()
680  << "Standard std::exception caught whilst finalizing tool '"
681  << toolName << "'" << endmsg << Exception.what() << endmsg;
682  sc = StatusCode::FAILURE;
683  }
684  catch (...)
685  {
686  error()
687  << "UNKNOWN Exception caught whilst finalizing tool '"
688  << toolName << "'" << endmsg;
689  sc = StatusCode::FAILURE;
690  }
691 
692  return sc;
693 
694 }
695 
696 //------------------------------------------------------------------------------
697 unsigned long ToolSvc::totalToolRefCount() const
698 //------------------------------------------------------------------------------
699 {
700  return totalRefCount( m_instancesTools );
701 }
702 //------------------------------------------------------------------------------
703 unsigned long ToolSvc::minimumToolRefCount() const
704 //------------------------------------------------------------------------------
705 {
706  auto i = std::min_element( std::begin(m_instancesTools), std::end(m_instancesTools),
707  [](const IAlgTool* lhs, const IAlgTool* rhs) {
708  return lhs->refCount() < rhs->refCount();
709  } );
710  return i!=std::end(m_instancesTools) ? (*i)->refCount() : 0;
711 }
712 
714  if ( !obs )
715  throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
716  m_observers.push_back(obs);
717 }
718 
720  auto i = std::find(m_observers.begin(),m_observers.end(),obs);
721  if (i!=m_observers.end()) m_observers.erase(i);
722 }
723 
724 //------------------------------------------------------------------------------
727 //------------------------------------------------------------------------------
728 {
729 
730  ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
731 
732  bool fail(false);
733  for ( auto& iTool : m_instancesTools ) {
734  ON_VERBOSE verbose() << iTool->name() << "::start()" << endmsg;
735 
736  if (UNLIKELY(!iTool->sysStart().isSuccess())) {
737  fail = true;
738  error() << iTool->name() << " failed to start()" << endmsg;
739  }
740 
741  }
742 
743  if (UNLIKELY(fail)) {
744  error() << "One or more AlgTools failed to start()" << endmsg;
745  return StatusCode::FAILURE;
746  }
747  return StatusCode::SUCCESS;
748 }
749 
750 //------------------------------------------------------------------------------
753 //------------------------------------------------------------------------------
754 {
755 
756  ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
757 
758  bool fail(false);
759  for ( auto& iTool : m_instancesTools ) {
760  ON_VERBOSE verbose() << iTool->name() << "::stop()" << endmsg;
761 
762  if (UNLIKELY(!iTool->sysStop().isSuccess())) {
763  fail = true;
764  error() << iTool->name() << " failed to stop()" << endmsg;
765  }
766 
767  }
768 
769  if (UNLIKELY(fail)) {
770  error() << "One or more AlgTools failed to stop()" << endmsg;
771  return StatusCode::FAILURE;
772  }
773  return StatusCode::SUCCESS;
774 }
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:359
tuple c
Definition: gaudirun.py:391
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
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:374
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
void unRegisterObserver(IToolSvc::Observer *obs) override
Definition: ToolSvc.cpp:719
def remove(file, logdir)
Definition: install.py:153
StatusCode finalize() override
Definition: Service.cpp:188
std::string nameTool(const std::string &nameByUser, const IInterface *parent)
Get Tool full name by combining nameByUser and "parent" part.
Definition: ToolSvc.cpp:623
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:244
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
unsigned long minimumToolRefCount() const
The minimum number of refCounts of all tools.
Definition: ToolSvc.cpp:703
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:407
STL namespace.
void registerObserver(IToolSvc::Observer *obs) override
Definition: ToolSvc.cpp:713
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:106
bool existsTool(const std::string &toolname) const
Check if the tool instance exists.
Definition: ToolSvc.cpp:647
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
StatusCode initialize() override
Initialize the service.
Definition: ToolSvc.cpp:52
This service manages tools.
Definition: ToolSvc.h:22
StatusCode setProperties()
Method for setting declared properties to the values specified in the jobOptions via the job option s...
Definition: AlgTool.cpp:177
StatusCode start() override
Definition: ToolSvc.cpp:726
Interface ID class.
Definition: IInterface.h:30
unsigned long totalToolRefCount() const
The total number of refCounts on all tools in the instancesTools list.
Definition: ToolSvc.cpp:697
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:656
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
virtual StatusCode registerAlgTool(const IAlgTool &)=0
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
Definition of the basic interface.
Definition: IInterface.h:234
std::vector< IAlgTool * > getTools() const override
Get pointers to all tool instances.
Definition: ToolSvc.cpp:368
virtual const std::string & tag() const
name tag for the exception, or exception type
virtual const IInterface * parent() const =0
The parent of the concrete AlgTool.
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
std::vector< IAlgTool * > m_instancesTools
Common Tools.
Definition: ToolSvc.h:101
virtual void onRetrieve(const IAlgTool *)
Definition: IToolSvc.h:248
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:44
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
#define ON_DEBUG
Definition: ToolSvc.cpp:20
StatusCode finalize() override
Finalize the service.
Definition: ToolSvc.cpp:74
#define UNLIKELY(x)
Definition: Kernel.h:126
void ignore() const
Definition: StatusCode.h:108
list i
Definition: ana.py:128
StatusCode stop() override
Definition: ToolSvc.cpp:752
#define ON_VERBOSE
Definition: ToolSvc.cpp:21
tuple toolname
Definition: gaudirun.py:327
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