Gaudi Framework, version v23r5

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

Generated at Wed Nov 28 2012 12:17:11 for Gaudi Framework, version v23r5 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004