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 #ifdef __ICC
15 // disable icc remark #177: declared but never referenced
16 // TODO: Remove. Problem with boost::lambda
17 #pragma warning(disable:177)
18 #endif
19 #include "boost/lambda/bind.hpp"
20 
21 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
22 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
23 
24 // Instantiation of a static factory class used by clients to create
25 // instances of this service
27 
28 namespace bl = boost::lambda;
29 
30 //------------------------------------------------------------------------------
31 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc )
32  //------------------------------------------------------------------------------
33  : base_class(name, svc),
34  m_pHistorySvc(0)
35  { }
36 
37 //------------------------------------------------------------------------------
39  //------------------------------------------------------------------------------
40 {
41 
42 }
43 
44 //------------------------------------------------------------------------------
46  //------------------------------------------------------------------------------
47 {
48 
49  // initialize the Service Base class
51  if (UNLIKELY(status.isFailure()))
52  {
53  error() << "Unable to initialize the Service" << endmsg;
54  return status;
55  }
56 
57  // set my own (ToolSvc) properties via the jobOptionService
58  if (UNLIKELY(setProperties().isFailure())) {
59  error() << "Unable to set base properties" << endmsg;
60  return StatusCode::FAILURE;
61  }
62 
63  return status;
64 }
65 
66 //------------------------------------------------------------------------------
68  //------------------------------------------------------------------------------
69 {
70  // Finalize and delete all left-over tools. Normally all tools created with
71  // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
72  // Several cases need to be covered:
73  // 1) Simple dependencies: no circular dependencies between tools,
74  // and tools not using other tools
75  // 2) Tools-using-tools (but no circular dependencies)
76  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
77  // b) release() is called in the tool destructor (e.g. via ToolHandle)
78  // 3) Circular dependencies between tools
79  // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
80  // b) release() is called in the tool destructor (e.g. via ToolHandle)
81  // 4) In addition to each of the above cases, refCounting of a particular tool
82  // might not have been done correctly in the code. Typically release()
83  // is not called, so we are left with a too high refCount.
84  // What to do with those, and how to avoid a crash while handling them...
85 
94  ListTools finalizedTools; // list of tools that have been finalized
95  info() << "Removing all tools created by ToolSvc" << endmsg;
96 
97  // Print out list of tools
98  ON_DEBUG {
99  MsgStream &log = debug();
100  log << " Tool List : ";
101  for ( ListTools::const_iterator iTool = m_instancesTools.begin();
102  iTool != m_instancesTools.end(); ++iTool ) {
103  log << (*iTool)->name() << ":" << refCountTool( *iTool ) << " ";
104  }
105  log << endmsg;
106  }
107 
108  //
109  // first pass: Finalize all tools (but don't delete them)
110  //
123  bool fail(false);
124  size_t toolCount = m_instancesTools.size();
125  unsigned long startRefCount = 0;
126  unsigned long endRefCount = totalToolRefCount();
127  unsigned long startMinRefCount = 0;
128  unsigned long endMinRefCount = minimumToolRefCount();
129  while ( toolCount > 0 &&
130  endRefCount > 0 &&
131  (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) {
132  ON_DEBUG if ( endMinRefCount != startMinRefCount ) {
133  debug() << toolCount << " tools left to finalize. Summed refCounts: "
134  << endRefCount << endmsg;
135  debug() << "Will finalize tools with refCount <= "
136  << endMinRefCount << endmsg;
137  }
138  startMinRefCount = endMinRefCount;
139  startRefCount = endRefCount;
140  unsigned long maxLoop = toolCount + 1;
141  while ( --maxLoop > 0 && m_instancesTools.size() > 0 ) {
142  IAlgTool* pTool = m_instancesTools.back();
143  // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
144  m_instancesTools.pop_back();
145  unsigned long count = refCountTool( pTool );
146  // cache tool name
147  std::string toolName = pTool->name();
148  if ( count <= startMinRefCount ) {
149  ON_DEBUG debug() << " Performing finalization of " << toolName
150  << " (refCount " << count << ")" << endmsg;
151  // finalize of one tool may trigger a release of another tool
152  // pTool->sysFinalize().ignore();
153  if (!finalizeTool(pTool).isSuccess()) {
154  warning() << " FAILURE finalizing " << toolName << endmsg;
155  fail = true;
156  }
157  // postpone deletion
158  finalizedTools.push_back(pTool);
159  } else {
160  // Place back in list to try again later
161  // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
162  ON_DEBUG debug() << " Delaying finalization of " << toolName
163  << " (refCount " << count << ")" << endmsg;
164  m_instancesTools.push_front(pTool);
165  }
166  } // end of inner loop
167  toolCount = m_instancesTools.size();
168  endRefCount = totalToolRefCount();
169  endMinRefCount = minimumToolRefCount();
170  }; // end of outer loop
171 
172  //
173  // Second pass: Delete all finalized tools
174  //
175  // Delete in the order of increasing number of refCounts.
176  // Loop over tools in the same order as the order in which they were finalized.
177  // All tools in the list of finalized tools are no longer in the instancesTools list.
178  // If a tool destructor calls releaseTool() on another tool, this will have no
179  // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
180  // If this 'other tool' is still in the instancesTools list, it may trigger finalization
181  // (in releaseTool()), deletion and removal from the instancesTools list.
182  // Therefore, the check on non-finalised tools should happen *after* the deletion
183  // of the finalized tools.
184  ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
185  unsigned long maxLoop = totalToolRefCount( finalizedTools ) + 1;
186  while ( --maxLoop > 0 && finalizedTools.size() > 0 ) {
187  IAlgTool* pTool = finalizedTools.front();
188  finalizedTools.pop_front();
189  unsigned long count = refCountTool( pTool );
190  if ( count == 1 ) {
191  ON_DEBUG debug() << " Performing deletion of " << pTool->name() << endmsg;
192  } else {
193  ON_VERBOSE verbose() << " Delaying deletion of " << pTool->name()
194  << " (refCount " << count << ")" << endmsg;
195  // Put it back at the end of the list if refCount still not zero
196  finalizedTools.push_back(pTool);
197  }
198  // do a forced release
199  pTool->release();
200  }
201 
202  // Error if by now not all tools are properly finalised
203  if ( !m_instancesTools.empty() ) {
204  error() << "Unable to finalize and delete the following tools : ";
205  for ( ListTools::const_iterator iTool = m_instancesTools.begin();
206  iTool != m_instancesTools.end(); ++iTool ) {
207  error() << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
208  }
209  error() << endmsg;
210  }
211 
212  // by now, all tools should be deleted and removed.
213  if ( finalizedTools.size() > 0 ) {
214  error() << "Failed to delete the following " << finalizedTools.size()
215  << " finalized tools. Bug in ToolSvc::finalize()?: ";
216  for ( ListTools::const_iterator iTool = finalizedTools.begin();
217  iTool != finalizedTools.end(); ++iTool ) {
218  error() << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
219  }
220  error() << endmsg;
221  }
222 
223  if ( 0 != m_pHistorySvc ) {
225  }
226 
227  // Finalize this specific service
228  if (! Service::finalize().isSuccess() || fail) {
229  return StatusCode::FAILURE;
230  } else {
231  return StatusCode::SUCCESS;
232  }
233 
234 
235 }
236 
237 // ===================================================================================
241 // ===================================================================================
242 namespace
243 {
244  const std::string s_PUBLIC = ":PUBLIC" ;
245 }
246 
247 //------------------------------------------------------------------------------
248 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
249  const InterfaceID& iid ,
250  IAlgTool*& tool ,
251  const IInterface* parent ,
252  bool createIf )
253 //------------------------------------------------------------------------------
254 {
255 
256  // protect against empty type
257  if ( tooltype.empty() ) {
258  error() << "retrieve(): No Tool Type/Name given" << endmsg;
259  return StatusCode::FAILURE;
260  }
261 
262  {
263  // check for tools, which by name is required to be public:
264  const std::string::size_type pos = tooltype.find ( s_PUBLIC ) ;
265  if ( std::string::npos != pos )
266  {
267  // set parent for PUBLIC tool
268  parent = this ;
269  return retrieve ( std::string( tooltype , 0 , pos ) ,
270  iid , tool , parent , createIf ) ;
271  }
272  }
273 
274  const std::string::size_type pos = tooltype.find('/');
275  if( std::string::npos == pos ) {
276  return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );
277  }
278  const std::string newtype ( tooltype , 0 , pos ) ;
279  const std::string newname ( tooltype , pos + 1 , std::string::npos ) ;
280  return retrieve ( newtype , newname , iid , tool , parent , createIf ) ;
281 }
282 
283 // ===================================================================================
284 
285 //------------------------------------------------------------------------------
286 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
287  const std::string& toolname ,
288  const InterfaceID& iid ,
289  IAlgTool*& tool ,
290  const IInterface* parent ,
291  bool createIf )
292  //------------------------------------------------------------------------------
293 {
294  // check the applicability of another method:
295  // ignore the provided name if it is empty or the type contains a name
296  if( toolname.empty() || (std::string::npos != tooltype.find('/')) )
297  { return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
298 
299  {
300  // check for tools, which by name is required to be public:
301  const std::string::size_type pos = toolname.find ( s_PUBLIC ) ;
302  if ( std::string::npos != pos )
303  {
304  // set parent for PUBLIC tool
305  parent = this ;
306  return retrieve ( tooltype , std::string( toolname , 0 , pos ) ,
307  iid , tool , parent , createIf ) ;
308  }
309  }
310 
311  IAlgTool* itool = 0;
313 
314  tool = 0;
315 
316  // If parent is not specified it means it is the ToolSvc itself
317  if( 0 == parent ) {
318  parent = this;
319  }
320  const std::string fullname = nameTool( toolname, parent );
321 
322  // Find tool in list of those already existing, and tell its
323  // interface that it has been used one more time
324  ListTools::const_iterator it;
325  for( it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it ) {
326  if( (*it)->name() == fullname ) {
327  ON_DEBUG debug() << "Retrieved tool " << toolname << endmsg;
328  itool = *it;
329  break;
330  }
331  }
332 
333  if ( 0 == itool ) {
334  // Instances of this tool do not exist, create an instance if desired
335  // otherwise return failure
336  if( UNLIKELY(!createIf) ) {
337  warning() << "Tool " << toolname
338  << " not found and creation not requested" << endmsg;
339  return sc;
340  }
341  else {
342  sc = create( tooltype, toolname, parent, itool );
343  if ( sc.isFailure() ) { return sc; }
344  }
345  }
346 
347  // Get the right interface of it
348  sc = itool->queryInterface( iid, (void**)&tool);
349  if( UNLIKELY(sc.isFailure()) ) {
350  error() << "Tool " << toolname
351  << " either does not implement the correct interface, or its version is incompatible"
352  << endmsg;
353  return sc;
354  }
358  if (!m_observers.empty()) {
359  std::for_each( m_observers.begin(),
360  m_observers.end(),
362  bl::_1,
363  itool));
364  }
365 
366  return sc;
367 }
368 //------------------------------------------------------------------------------
369 std::vector<std::string> ToolSvc::getInstances( const std::string& toolType )
370 //------------------------------------------------------------------------------
371 {
372 
373  std::vector<std::string> tools;
374 
375  for(auto tool: m_instancesTools) {
376  if (tool->type() == toolType) {
377  tools.push_back( tool->name() );
378  }
379  }
380 
381  return tools;
382 
383 }
384 //------------------------------------------------------------------------------
385 std::vector<std::string> ToolSvc::getInstances() const
386 //------------------------------------------------------------------------------
387 {
388  std::vector<std::string> tools{m_instancesTools.size()};
389  std::transform(std::begin(m_instancesTools), std::end(m_instancesTools),
390  std::begin(tools),
391  [](IAlgTool* tool) {return tool->name();});
392  return tools;
393 }
394 //------------------------------------------------------------------------------
395 std::vector<IAlgTool*> ToolSvc::getTools() const
396 //------------------------------------------------------------------------------
397 {
398  return std::vector<IAlgTool*>{std::begin(m_instancesTools),
400 }
401 //------------------------------------------------------------------------------
403  //------------------------------------------------------------------------------
404 {
406  // test if tool is in known list (protect trying to access a previously deleted tool)
407  if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(),
408  m_instancesTools.rend(),
409  tool ) ) {
410  unsigned long count = refCountTool(tool);
411  if ( count == 1 ) {
412  MsgStream log( msgSvc(), name() );
413  // finalize the tool
414 
416  // We are being called during ToolSvc::finalize()
417  // message format matches the one in ToolSvc::finalize()
418  log << MSG::DEBUG << " Performing finalization of " << tool->name()
419  << " (refCount " << count << ")" << endmsg;
420  // message format matches the one in ToolSvc::finalize()
421  log << MSG::DEBUG << " Performing deletion of " << tool->name() << endmsg;
422  } else {
423  log << MSG::DEBUG << "Performing finalization and deletion of " << tool->name() << endmsg;
424  }
425  sc = finalizeTool(tool);
426  // remove from known tools...
427  m_instancesTools.remove(tool);
428  }
429  tool->release();
430  }
431 
432  return sc;
433 }
434 
435 //------------------------------------------------------------------------------
436 StatusCode ToolSvc::create(const std::string& tooltype,
437  const IInterface* parent,
438  IAlgTool*& tool)
439  //------------------------------------------------------------------------------
440 {
441  const std::string & toolname = tooltype;
442  return create( tooltype, toolname, parent, tool);
443 }
444 
445 namespace {
448 class ToolCreateGuard {
449 public:
450  ToolCreateGuard(ToolSvc::ListTools &listTools):
451  m_list(listTools),
452  m_tool(0)
453  {}
455  void set(IAlgTool* tool) {
456  if (m_tool) { // remove previous content
457  m_list.remove(m_tool);
458  delete m_tool;
459  }
460  if (tool) { // set new content
461  m_tool = tool;
462  m_list.push_back(m_tool);
463  }
464  }
465  ToolCreateGuard& operator=(IAlgTool* tool) {
466  set(tool);
467  return *this;
468  }
470  IAlgTool* get() {
471  return m_tool;
472  }
473  IAlgTool* operator->() const {
474  assert(m_tool != 0);
475  return m_tool;
476  }
478  IAlgTool* release() {
479  IAlgTool* tool = m_tool;
480  m_tool = 0;
481  return tool;
482  }
484  ~ToolCreateGuard(){
485  set(0);
486  }
487 private:
489  ToolSvc::ListTools& m_list;
491  IAlgTool* m_tool;
492 };
493 }
494 //------------------------------------------------------------------------------
495 StatusCode ToolSvc::create(const std::string& tooltype,
496  const std::string& toolname,
497  const IInterface* parent,
498  IAlgTool*& tool)
499  //------------------------------------------------------------------------------
500 {
501  // protect against empty type
502  if ( UNLIKELY(tooltype.empty()) ) {
503  error() << "create(): No Tool Type given" << endmsg;
504  return StatusCode::FAILURE;
505  }
506 
507  // If parent has not been specified, assume it is the ToolSvc
508  if ( 0 == parent ) parent = this;
509 
510  tool = 0;
511  // Automatically deletes the tool if not explicitly kept (i.e. on success).
512  // The tool is removed from the list of known tools too.
513  ToolCreateGuard toolguard(m_instancesTools);
514 
515  // Check if the tool already exist : this should never happen
516  const std::string fullname = nameTool(toolname, parent);
517  if( UNLIKELY(existsTool(fullname)) ) {
518  error() << "Tool " << fullname << " already exists" << endmsg;
519  return StatusCode::FAILURE;
520  }
521  // instantiate the tool using the factory
522  try {
523  toolguard = AlgTool::Factory::create(tooltype, tooltype, fullname, parent);
524  if ( UNLIKELY(! toolguard.get()) ){
525  error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
526  return StatusCode::FAILURE;
527  }
528  }
529  catch ( const GaudiException& Exception ) {
530  // (1) perform the printout of message
531  fatal() << "Exception with tag=" << Exception.tag()
532  << " is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
533  // (2) print the exception itself
534  // (NB! - GaudiException is a linked list of all "previous exceptions")
535  fatal() << Exception << endmsg;
536  return StatusCode::FAILURE;
537  }
538  catch( const std::exception& Exception ) {
539  // (1) perform the printout of message
540  fatal() << "Standard std::exception is caught whilst instantiating tool '"
541  << tooltype << "'" << endmsg;
542  // (2) print the exception itself
543  // (NB! - GaudiException is a linked list of all "previous exceptions")
544  fatal() << Exception.what() << endmsg;
545  return StatusCode::FAILURE;
546  }
547  catch(...) {
548  // (1) perform the printout
549  fatal() << "UNKNOWN Exception is caught whilst instantiating tool '"
550  << tooltype << "'" << endmsg;
551  return StatusCode::FAILURE;
552  }
553  ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
554 
555  // Since only AlgTool has the setProperties() method it is necessary to cast
556  // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
557  // service
558  AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get());
559  if ( mytool != 0 ) {
560  StatusCode sc = mytool->setProperties();
561  if ( UNLIKELY(sc.isFailure()) ) {
562  error() << "Error setting properties for tool '"
563  << fullname << "'" << endmsg;
564  return sc;
565  }
566  }
567 
568  // Initialize the Tool
570  try {
571  sc = toolguard->sysInitialize();
572  }
573  // Catch any exceptions
574  catch ( const GaudiException & Exception )
575  {
576  error()
577  << "GaudiException with tag=" << Exception.tag()
578  << " caught whilst initializing tool '" << fullname << "'" << endmsg
579  << Exception << endmsg;
580  return StatusCode::FAILURE;
581  }
582  catch( const std::exception & Exception )
583  {
584  error()
585  << "Standard std::exception caught whilst initializing tool '"
586  << fullname << "'" << endmsg << Exception.what() << endmsg;
587  return StatusCode::FAILURE;
588  }
589  catch (...)
590  {
591  error()
592  << "UNKNOWN Exception caught whilst initializing tool '"
593  << fullname << "'" << endmsg;
594  return StatusCode::FAILURE;
595  }
596 
597  // Status of tool initialization
598  if ( UNLIKELY(sc.isFailure()) ) {
599  error() << "Error initializing tool '" << fullname << "'" << endmsg;
600  return sc;
601  }
602 
603  // Start the tool if we are running.
605  sc = toolguard->sysStart();
606 
607  if (UNLIKELY(sc.isFailure())) {
608  error() << "Error starting tool '" << fullname << "'" << endmsg;
609  return sc;
610  }
611  }
612 
613 
614  // The tool has been successfully created and initialized,
615  // so we the guard can be released
616  tool = toolguard.release();
617 
621  if (!m_observers.empty()) {
622  std::for_each( m_observers.begin(),
623  m_observers.end(),
625  bl::_1,
626  tool));
627  }
628  // TODO: replace by generic callback
629  // Register the tool with the HistorySvc
630  if (m_pHistorySvc != 0 ||
631  service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
633  }
634 
635  return StatusCode::SUCCESS;
636 
637 }
638 
639 //------------------------------------------------------------------------------
640 std::string ToolSvc::nameTool( const std::string& toolname,
641  const IInterface* parent )
642  //------------------------------------------------------------------------------
643 {
644 
645  std::string fullname = "";
646  if ( parent == 0 ) { return this->name() + "." + toolname; } // RETURN
647 
648 
649  IInterface* cparent = const_cast<IInterface*>( parent ) ;
650  // check that parent has a name!
651  INamedInterface* _p = 0 ;
652  StatusCode sc = cparent->queryInterface( INamedInterface::interfaceID() , pp_cast<void>(&_p) ) ;
653  if ( sc.isSuccess() )
654  {
655  fullname = _p->name() + "." + toolname ;
656  _p->release() ;
657  return fullname ; // RETURN
658  }
659 
660  MsgStream log ( msgSvc(), name() );
661  log << MSG::ERROR
662  << "Private Tools only allowed for components implementing INamedInterface"
663  << endmsg;
664  //
665  return "." + toolname ;
666 }
667 
668 //------------------------------------------------------------------------------
669 bool ToolSvc::existsTool( const std::string& fullname) const
670  //------------------------------------------------------------------------------
671 {
672  for ( ListTools::const_iterator it = m_instancesTools.begin();
673  it != m_instancesTools.end(); ++it ) {
674  if ( (*it)->name() == fullname ) { return true; }
675  }
676  return false;
677 }
678 
679 //------------------------------------------------------------------------------
681  //------------------------------------------------------------------------------
682 {
683 
684  // Cache tool name in case of errors
685  const std::string toolName = itool->name();
686  StatusCode sc;
687 
688  // Finalise the tool inside a try block
689  try {
690  sc = itool->sysFinalize();
691  }
692  // Catch any exceptions
693  catch ( const GaudiException & Exception )
694  {
695  error()
696  << "GaudiException with tag=" << Exception.tag()
697  << " caught whilst finalizing tool '" << toolName << "'" << endmsg
698  << Exception << endmsg;
699  sc = StatusCode::FAILURE;
700  }
701  catch( const std::exception & Exception )
702  {
703  error()
704  << "Standard std::exception caught whilst finalizing tool '"
705  << toolName << "'" << endmsg << Exception.what() << endmsg;
706  sc = StatusCode::FAILURE;
707  }
708  catch (...)
709  {
710  error()
711  << "UNKNOWN Exception caught whilst finalizing tool '"
712  << toolName << "'" << endmsg;
713  sc = StatusCode::FAILURE;
714  }
715 
716  return sc;
717 
718 }
719 
720 //------------------------------------------------------------------------------
721 unsigned long ToolSvc::totalToolRefCount( const ToolSvc::ListTools& toolList ) const
722 //------------------------------------------------------------------------------
723 {
724  unsigned long count = 0;
725  for ( ListTools::const_iterator iTool = toolList.begin();
726  iTool != toolList.end(); ++iTool ) {
727  count += refCountTool( *iTool );
728  }
729  return count;
730 }
731 
732 //------------------------------------------------------------------------------
733 unsigned long ToolSvc::totalToolRefCount() const
734 //------------------------------------------------------------------------------
735 {
737 }
738 //------------------------------------------------------------------------------
739 unsigned long ToolSvc::minimumToolRefCount() const
740 //------------------------------------------------------------------------------
741 {
742  unsigned long count = 0;
743  if ( m_instancesTools.size() > 0 ) {
744  ListTools::const_iterator iTool = m_instancesTools.begin();
745  // start with first
746  count = refCountTool( *iTool );
747  // then compare the others
748  for( ++iTool; iTool != m_instancesTools.end(); ++iTool ) {
749  count = std::min( count, refCountTool( *iTool ) );
750  }
751  }
752  return count;
753 }
754 
756  if ( 0 == obs )
757  throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
758  m_observers.push_back(obs);
759 }
760 
762  std::vector<IToolSvc::Observer*>::iterator i =
763  find(m_observers.begin(),m_observers.end(),obs);
764  if (i!=m_observers.end()) m_observers.erase(i);
765 }
766 
767 //------------------------------------------------------------------------------
770 //------------------------------------------------------------------------------
771 {
772 
773  ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
774 
775  bool fail(false);
776  for ( ListTools::const_iterator iTool = m_instancesTools.begin();
777  iTool != m_instancesTools.end(); ++iTool ) {
778  ON_VERBOSE verbose() << (*iTool)->name() << "::start()" << endmsg;
779 
780  if (UNLIKELY(!(*iTool)->sysStart().isSuccess())) {
781  fail = true;
782  error() << (*iTool)->name() << " failed to start()" << endmsg;
783  }
784 
785  }
786 
787  if (UNLIKELY(fail)) {
788  error() << "One or more AlgTools failed to start()" << endmsg;
789  return StatusCode::FAILURE;
790  } else {
791  return StatusCode::SUCCESS;
792  }
793 
794 }
795 
796 //------------------------------------------------------------------------------
799 //------------------------------------------------------------------------------
800 {
801 
802  ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
803 
804  bool fail(false);
805  for ( ListTools::const_iterator iTool = m_instancesTools.begin();
806  iTool != m_instancesTools.end(); ++iTool ) {
807  ON_VERBOSE verbose() << (*iTool)->name() << "::stop()" << endmsg;
808 
809  if (UNLIKELY(!(*iTool)->sysStop().isSuccess())) {
810  fail = true;
811  error() << (*iTool)->name() << " failed to stop()" << endmsg;
812  }
813 
814  }
815 
816  if (UNLIKELY(fail)) {
817  error() << "One or more AlgTools failed to stop()" << endmsg;
818  return StatusCode::FAILURE;
819  } else {
820  return StatusCode::SUCCESS;
821  }
822 
823 }
IHistorySvc * m_pHistorySvc
Pointer to HistorySvc.
Definition: ToolSvc.h:114
virtual void unRegisterObserver(IToolSvc::Observer *obs)
Definition: ToolSvc.cpp:761
Gaudi::StateMachine::State m_targetState
Service state.
Definition: Service.h:248
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
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:26
virtual ~ToolSvc()
Destructor.
Definition: ToolSvc.cpp:38
virtual StatusCode finalize()
Finalize the service.
Definition: ToolSvc.cpp:67
Gaudi::StateMachine::State m_state
Service state.
Definition: Service.h:246
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
std::string nameTool(const std::string &nameByUser, const IInterface *parent)
Get Tool full name by combining nameByUser and "parent" part.
Definition: ToolSvc.cpp:640
allow call-backs when a tool is a created or retrieved
Definition: IToolSvc.h:240
SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
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:739
StatusCode create(const std::string &type, const IInterface *parent, IAlgTool *&tool)
Create Tool standard way with automatically assigned name.
Definition: ToolSvc.cpp:436
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
STL namespace.
ListTools m_instancesTools
Common Tools.
Definition: ToolSvc.h:111
std::vector< IToolSvc::Observer * > m_observers
Definition: ToolSvc.h:116
bool existsTool(const std::string &toolname) const
Check if the tool instance exists.
Definition: ToolSvc.cpp:669
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:85
This service manages tools.
Definition: ToolSvc.h:23
StatusCode setProperties()
Method for setting declared properties to the values specified in the jobOptions via the job option s...
Definition: AlgTool.cpp:151
virtual const std::string & name() const =0
Retrieve the name of the instance.
Gaudi::InterfaceId< IInterface, 0, 0 > iid
Interface ID.
Definition: IInterface.h:164
virtual StatusCode releaseTool(IAlgTool *tool)
Release tool.
Definition: ToolSvc.cpp:402
virtual void onCreate(const IAlgTool *)
Definition: IToolSvc.h:243
Interface ID class.
Definition: IInterface.h:55
unsigned long totalToolRefCount() const
The total number of refCounts on all tools in the instancesTools list.
Definition: ToolSvc.cpp:733
StatusCode finalizeTool(IAlgTool *itool) const
Finalize the given tool, with exception handling.
Definition: ToolSvc.cpp:680
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
virtual StatusCode stop()
Stop (from RUNNING to INITIALIZED).
Definition: ToolSvc.cpp:798
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
virtual StatusCode registerAlgTool(const IAlgTool &)=0
Definition of the basic interface.
Definition: IInterface.h:160
virtual void registerObserver(IToolSvc::Observer *obs)
Definition: ToolSvc.cpp:755
virtual const std::string & tag() const
name tag for the exception, or exception type
StatusCode setProperties()
Method for setting declared properties to the values specified for the job.
Definition: Service.cpp:373
virtual const std::string & name() const
Retrieve name of the service.
Definition: Service.cpp:329
tuple end
Definition: IOTest.py:101
#define min(a, b)
IInterface compliant class extending IInterface with the name() method.
virtual unsigned long release()=0
Release Interface instance.
virtual std::vector< std::string > getInstances() const
Get names of all tool instances.
Definition: ToolSvc.cpp:385
virtual StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
Definition: Service.cpp:72
virtual StatusCode retrieve(const std::string &type, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent, bool createIf)
Retrieve tool, create it by default as common tool if it does not already exist.
Definition: ToolSvc.cpp:248
virtual StatusCode initialize()
Initialize the service.
Definition: ToolSvc.cpp:45
virtual void onRetrieve(const IAlgTool *)
Definition: IToolSvc.h:244
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:34
The interface implemented by the AlgTool base class.
Definition: IAlgTool.h:23
#define ON_DEBUG
Definition: ToolSvc.cpp:21
Templated class to add the standard messaging functionalities.
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
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:143
#define UNLIKELY(x)
Definition: Kernel.h:127
virtual StatusCode start()
Start (from INITIALIZED to RUNNING).
Definition: ToolSvc.cpp:769
void ignore() const
Definition: StatusCode.h:107
std::list< IAlgTool * > ListTools
Definition: ToolSvc.h:28
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
list i
Definition: ana.py:128
static const InterfaceID & interfaceID()
Return an instance of InterfaceID identifying the interface.
Definition: IInterface.h:171
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual std::vector< IAlgTool * > getTools() const
Get pointers to all tool instances.
Definition: ToolSvc.cpp:395
#define ON_VERBOSE
Definition: ToolSvc.cpp:22
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
Definition: Service.cpp:197
tuple toolname
Definition: gaudirun.py:326
virtual StatusCode queryInterface(const InterfaceID &ti, void **pp)=0
Set the void** to the pointer to the requested interface of the instance.
unsigned long refCountTool(IAlgTool *tool) const
Get current refcount for tool.
Definition: ToolSvc.h:79