00001
00002
00003
00004 #include "GaudiKernel/MsgStream.h"
00005 #include "GaudiKernel/Service.h"
00006 #include "GaudiKernel/SvcFactory.h"
00007 #include "GaudiKernel/ISvcLocator.h"
00008 #include "GaudiKernel/IAlgorithm.h"
00009 #include "GaudiKernel/GaudiException.h"
00010 #include "GaudiKernel/AlgTool.h"
00011 #include "GaudiKernel/IHistorySvc.h"
00012 #include "GaudiKernel/ToolFactory.h"
00013 #include "ToolSvc.h"
00014 #include <algorithm>
00015 #include <map>
00016 #include <string>
00017 #include <cassert>
00018 #include "boost/lambda/bind.hpp"
00019
00020
00021
00022 DECLARE_SERVICE_FACTORY(ToolSvc)
00023
00024 using ROOT::Reflex::PluginService;
00025 namespace bl = boost::lambda;
00026
00027
00028 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc )
00029
00030 : base_class(name, svc),
00031 m_pHistorySvc(0)
00032 { }
00033
00034
00035 ToolSvc::~ToolSvc()
00036
00037 {
00038
00039 }
00040
00041
00042 StatusCode ToolSvc::initialize()
00043
00044 {
00045
00046
00047 StatusCode status = Service::initialize();
00048 if ( status.isFailure() )
00049 {
00050 MsgStream log( msgSvc(), name() );
00051 log << MSG::ERROR << "Unable to initialize the Service" << endmsg;
00052 return status;
00053 }
00054
00055
00056 if (setProperties().isFailure()) {
00057 MsgStream log( msgSvc(), name() );
00058 log << MSG::ERROR << "Unable to set base properties" << endmsg;
00059 return StatusCode::FAILURE;
00060 }
00061
00062 return status;
00063 }
00064
00065
00066 StatusCode ToolSvc::finalize()
00067
00068 {
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00093 MsgStream log( msgSvc(), name() );
00094 ListTools finalizedTools;
00095 log << MSG::INFO << "Removing all tools created by ToolSvc" << endmsg;
00096
00097
00098 log << MSG::DEBUG << " Tool List : ";
00099 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00100 iTool != m_instancesTools.end(); ++iTool ) {
00101 log << (*iTool)->name() << ":" << refCountTool( *iTool ) << " ";
00102 }
00103 log << endmsg;
00104
00105
00106
00107
00120 bool fail(false);
00121 size_t toolCount = m_instancesTools.size();
00122 unsigned long startRefCount = 0;
00123 unsigned long endRefCount = totalToolRefCount();
00124 unsigned long startMinRefCount = 0;
00125 unsigned long endMinRefCount = minimumToolRefCount();
00126 while ( toolCount > 0 &&
00127 endRefCount > 0 &&
00128 (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) {
00129 if ( endMinRefCount != startMinRefCount ) {
00130 log << MSG::DEBUG << toolCount << " tools left to finalize. Summed refCounts: "
00131 << endRefCount << endmsg;
00132 log << MSG::DEBUG << "Will finalize tools with refCount <= "
00133 << endMinRefCount << endmsg;
00134 }
00135 startMinRefCount = endMinRefCount;
00136 startRefCount = endRefCount;
00137 unsigned long maxLoop = toolCount + 1;
00138 while ( --maxLoop > 0 && m_instancesTools.size() > 0 ) {
00139 IAlgTool* pTool = m_instancesTools.back();
00140
00141 m_instancesTools.pop_back();
00142 unsigned long count = refCountTool( pTool );
00143
00144 std::string toolName = pTool->name();
00145 if ( count <= startMinRefCount ) {
00146 log << MSG::DEBUG << " Performing finalization of " << toolName
00147 << " (refCount " << count << ")" << endmsg;
00148
00149
00150 if (!finalizeTool(pTool).isSuccess()) fail = true;
00151
00152 finalizedTools.push_back(pTool);
00153 } else {
00154
00155
00156 log << MSG::DEBUG << " Delaying finalization of " << toolName
00157 << " (refCount " << count << ")" << endmsg;
00158 m_instancesTools.push_front(pTool);
00159 }
00160 }
00161 toolCount = m_instancesTools.size();
00162 endRefCount = totalToolRefCount();
00163 endMinRefCount = minimumToolRefCount();
00164 };
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 log << MSG::DEBUG << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
00179 unsigned long maxLoop = totalToolRefCount( finalizedTools ) + 1;
00180 while ( --maxLoop > 0 && finalizedTools.size() > 0 ) {
00181 IAlgTool* pTool = finalizedTools.front();
00182 finalizedTools.pop_front();
00183 unsigned long count = refCountTool( pTool );
00184 if ( count == 1 ) {
00185 log << MSG::DEBUG << " Performing deletion of " << pTool->name() << endmsg;
00186 } else {
00187 log << MSG::VERBOSE << " Delaying deletion of " << pTool->name()
00188 << " (refCount " << count << ")" << endmsg;
00189
00190 finalizedTools.push_back(pTool);
00191 }
00192
00193 pTool->release();
00194 }
00195
00196
00197 if ( !m_instancesTools.empty() ) {
00198 log << MSG::ERROR << "Unable to finalize and delete the following tools : ";
00199 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00200 iTool != m_instancesTools.end(); ++iTool ) {
00201 log << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
00202 }
00203 log << endmsg;
00204 }
00205
00206
00207 if ( finalizedTools.size() > 0 ) {
00208 log << MSG::ERROR << "Failed to delete the following " << finalizedTools.size()
00209 << " finalized tools. Bug in ToolSvc::finalize()?: ";
00210 for ( ListTools::const_iterator iTool = finalizedTools.begin();
00211 iTool != finalizedTools.end(); ++iTool ) {
00212 log << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
00213 }
00214 log << endmsg;
00215 }
00216
00217 if ( 0 != m_pHistorySvc ) {
00218 m_pHistorySvc->release();
00219 }
00220
00221
00222 if (! Service::finalize().isSuccess() || fail) {
00223 return StatusCode::FAILURE;
00224 } else {
00225 return StatusCode::SUCCESS;
00226 }
00227
00228
00229 }
00230
00231
00235
00236 namespace
00237 {
00238 const std::string s_PUBLIC = ":PUBLIC" ;
00239 }
00240
00241
00242 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
00243 const InterfaceID& iid ,
00244 IAlgTool*& tool ,
00245 const IInterface* parent ,
00246 bool createIf )
00247
00248 {
00249
00250
00251 if ( tooltype.empty() ) {
00252 MsgStream log( msgSvc(), name() );
00253 log << MSG::ERROR << "retrieve(): No Tool Type/Name given" << endmsg;
00254 return StatusCode::FAILURE;
00255 }
00256
00257 {
00258
00259 const std::string::size_type pos = tooltype.find ( s_PUBLIC ) ;
00260 if ( std::string::npos != pos )
00261 {
00262
00263 parent = this ;
00264 return retrieve ( std::string( tooltype , 0 , pos ) ,
00265 iid , tool , parent , createIf ) ;
00266 }
00267 }
00268
00269 const std::string::size_type pos = tooltype.find('/');
00270 if( std::string::npos == pos )
00271 { return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );}
00272 const std::string newtype ( tooltype , 0 , pos ) ;
00273 const std::string newname ( tooltype , pos + 1 , std::string::npos ) ;
00274 return retrieve ( newtype , newname , iid , tool , parent , createIf ) ;
00275 }
00276
00277
00278
00279
00280 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
00281 const std::string& toolname ,
00282 const InterfaceID& iid ,
00283 IAlgTool*& tool ,
00284 const IInterface* parent ,
00285 bool createIf )
00286
00287 {
00288 MsgStream log( msgSvc(), name() );
00289
00290
00291
00292 if( toolname.empty() || (std::string::npos != tooltype.find('/')) )
00293 { return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
00294
00295 {
00296
00297 const std::string::size_type pos = toolname.find ( s_PUBLIC ) ;
00298 if ( std::string::npos != pos )
00299 {
00300
00301 parent = this ;
00302 return retrieve ( tooltype , std::string( toolname , 0 , pos ) ,
00303 iid , tool , parent , createIf ) ;
00304 }
00305 }
00306
00307 IAlgTool* itool = 0;
00308 StatusCode sc(StatusCode::FAILURE);
00309
00310 tool = 0;
00311
00312
00313 if( 0 == parent ) {
00314 parent = this;
00315 }
00316 const std::string fullname = nameTool( toolname, parent );
00317
00318
00319
00320 ListTools::const_iterator it;
00321 for( it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it ) {
00322 if( (*it)->name() == fullname ) {
00323 log << MSG::DEBUG << "Retrieved tool " << toolname << endmsg;
00324 itool = *it;
00325 break;
00326 }
00327 }
00328
00329 if ( 0 == itool ) {
00330
00331
00332 if( !createIf ) {
00333 log << MSG::WARNING << "Tool " << toolname
00334 << " not found and creation not requested" << endmsg;
00335 return sc;
00336 }
00337 else {
00338 sc = create( tooltype, toolname, parent, itool );
00339 if ( sc.isFailure() ) { return sc; }
00340 }
00341 }
00342
00343
00344 sc = itool->queryInterface( iid, (void**)&tool);
00345 if( sc.isFailure() ) {
00346 log << MSG::ERROR << "Tool " << toolname
00347 << " either does not implement the correct interface, or its version is incompatible"
00348 << endmsg;
00349 return sc;
00350 }
00354 if (!m_observers.empty()) {
00355 std::for_each( m_observers.begin(),
00356 m_observers.end(),
00357 bl::bind(&IToolSvc::Observer::onRetrieve,
00358 bl::_1,
00359 itool));
00360 }
00361
00362 return sc;
00363 }
00364
00365 std::vector<std::string> ToolSvc::getInstances( const std::string& toolType )
00366
00367 {
00368
00369 std::vector<std::string> tools;
00370
00371 ListTools::const_iterator it;
00372 for (it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it) {
00373 if ((*it)->type() == toolType) {
00374 tools.push_back( (*it)->name() );
00375 }
00376 }
00377
00378 return tools;
00379
00380 }
00381
00382 StatusCode ToolSvc::releaseTool( IAlgTool* tool )
00383
00384 {
00385 StatusCode sc(StatusCode::SUCCESS);
00386
00387 if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(),
00388 m_instancesTools.rend(),
00389 tool ) ) {
00390 unsigned long count = refCountTool(tool);
00391 if ( count == 1 ) {
00392 MsgStream log( msgSvc(), name() );
00393
00394
00395 if ( Gaudi::StateMachine::OFFLINE == m_targetState ) {
00396
00397
00398 log << MSG::DEBUG << " Performing finalization of " << tool->name()
00399 << " (refCount " << count << ")" << endmsg;
00400
00401 log << MSG::DEBUG << " Performing deletion of " << tool->name() << endmsg;
00402 } else {
00403 log << MSG::DEBUG << "Performing finalization and deletion of " << tool->name() << endmsg;
00404 }
00405 sc = finalizeTool(tool);
00406
00407 m_instancesTools.remove(tool);
00408 }
00409 tool->release();
00410 }
00411
00412 return sc;
00413 }
00414
00415
00416 StatusCode ToolSvc::create(const std::string& tooltype,
00417 const IInterface* parent,
00418 IAlgTool*& tool)
00419
00420 {
00421 const std::string & toolname = tooltype;
00422 return create( tooltype, toolname, parent, tool);
00423 }
00424
00425 namespace {
00428 class ToolCreateGuard {
00429 public:
00430 ToolCreateGuard(ToolSvc::ListTools &listTools):
00431 m_list(listTools),
00432 m_tool(0)
00433 {}
00435 void set(IAlgTool* tool) {
00436 if (m_tool) {
00437 m_list.remove(m_tool);
00438 delete m_tool;
00439 }
00440 if (tool) {
00441 m_tool = tool;
00442 m_list.push_back(m_tool);
00443 }
00444 }
00445 ToolCreateGuard& operator=(IAlgTool* tool) {
00446 set(tool);
00447 return *this;
00448 }
00450 IAlgTool* get() {
00451 return m_tool;
00452 }
00453 IAlgTool& operator*() const {
00454 assert(m_tool != 0);
00455 return *m_tool;
00456 }
00457 IAlgTool* operator->() const {
00458 assert(m_tool != 0);
00459 return m_tool;
00460 }
00462 IAlgTool* release() {
00463 IAlgTool* tool = m_tool;
00464 m_tool = 0;
00465 return tool;
00466 }
00468 ~ToolCreateGuard(){
00469 set(0);
00470 }
00471 private:
00473 ToolSvc::ListTools& m_list;
00475 IAlgTool* m_tool;
00476 };
00477 }
00478
00479 StatusCode ToolSvc::create(const std::string& tooltype,
00480 const std::string& toolname,
00481 const IInterface* parent,
00482 IAlgTool*& tool)
00483
00484 {
00485 MsgStream log( msgSvc(), name() );
00486
00487 if ( tooltype.empty() ) {
00488 log << MSG::ERROR << "create(): No Tool Type given" << endmsg;
00489 return StatusCode::FAILURE;
00490 }
00491
00492
00493 if ( 0 == parent ) parent = this;
00494
00495 tool = 0;
00496
00497
00498 ToolCreateGuard toolguard(m_instancesTools);
00499
00500
00501 const std::string fullname = nameTool(toolname, parent);
00502 if( existsTool( fullname ) ) {
00503 log << MSG::ERROR << "Tool " << fullname << " already exists" << endmsg;
00504 return StatusCode::FAILURE;
00505 }
00506
00507 try {
00508 toolguard = PluginService::Create<IAlgTool*>(tooltype, tooltype, fullname, parent);
00509 if ( ! toolguard.get() ){
00510 log << MSG::ERROR
00511 << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
00512 return StatusCode::FAILURE;
00513 }
00514 }
00515 catch ( const GaudiException& Exception ) {
00516
00517 MsgStream log ( msgSvc() , name() );
00518 log << MSG::FATAL << "Exception with tag=" << Exception.tag()
00519 << " is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
00520
00521
00522 log << MSG::FATAL << Exception << endmsg;
00523 return StatusCode::FAILURE;
00524 }
00525 catch( const std::exception& Exception ) {
00526
00527 MsgStream log ( msgSvc() , name() );
00528 log << MSG::FATAL
00529 << "Standard std::exception is caught whilst instantiating tool '"
00530 << tooltype << "'" << endmsg;
00531
00532
00533 log << MSG::FATAL << Exception.what() << endmsg;
00534 return StatusCode::FAILURE;
00535 }
00536 catch(...) {
00537
00538 MsgStream log ( msgSvc() , name() );
00539 log << MSG::FATAL << "UNKNOWN Exception is caught whilst instantiating tool '"
00540 << tooltype << "'" << endmsg;
00541 return StatusCode::FAILURE;
00542 }
00543 log << MSG::VERBOSE << "Created tool " << tooltype << "/" << fullname << endmsg;
00544
00545
00546
00547
00548 AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get());
00549 if ( mytool != 0 ) {
00550 StatusCode sc = mytool->setProperties();
00551 if ( sc.isFailure() ) {
00552 MsgStream log ( msgSvc() , name() );
00553 log << MSG::ERROR << "Error setting properties for tool '"
00554 << fullname << "'" << endmsg;
00555 return sc;
00556 }
00557 }
00558
00559
00560 StatusCode sc (StatusCode::FAILURE,true);
00561 try { sc = toolguard->sysInitialize(); }
00562
00563
00564 catch ( const GaudiException & Exception )
00565 {
00566 MsgStream msg ( msgSvc(), name() );
00567 msg << MSG::ERROR
00568 << "GaudiException with tag=" << Exception.tag()
00569 << " caught whilst initializing tool '" << fullname << "'" << endmsg
00570 << Exception << endmsg;
00571 return StatusCode::FAILURE;
00572 }
00573 catch( const std::exception & Exception )
00574 {
00575 MsgStream msg ( msgSvc(), name() );
00576 msg << MSG::ERROR
00577 << "Standard std::exception caught whilst initializing tool '"
00578 << fullname << "'" << endmsg << Exception.what() << endmsg;
00579 return StatusCode::FAILURE;
00580 }
00581 catch (...)
00582 {
00583 MsgStream msg ( msgSvc(), name() );
00584 msg << MSG::ERROR
00585 << "UNKNOWN Exception caught whilst initializing tool '"
00586 << fullname << "'" << endmsg;
00587 return StatusCode::FAILURE;
00588 }
00589
00590
00591 if ( sc.isFailure() ) {
00592 MsgStream log( msgSvc(), name() );
00593 log << MSG::ERROR << "Error initializing tool '" << fullname << "'" << endmsg;
00594 return sc;
00595 }
00596
00597
00598 if (m_state == Gaudi::StateMachine::RUNNING) {
00599 sc = toolguard->sysStart();
00600
00601 if (sc.isFailure()) {
00602 MsgStream log( msgSvc(), name() );
00603 log << MSG::ERROR << "Error starting tool '" << fullname << "'" << endmsg;
00604 return sc;
00605 }
00606 }
00607
00608
00609
00610
00611 tool = toolguard.release();
00612
00616 if (!m_observers.empty()) {
00617 std::for_each( m_observers.begin(),
00618 m_observers.end(),
00619 bl::bind(&IToolSvc::Observer::onCreate,
00620 bl::_1,
00621 tool));
00622 }
00623
00624
00625 if (m_pHistorySvc != 0 ||
00626 service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
00627 m_pHistorySvc->registerAlgTool(*tool).ignore();
00628 }
00629
00630 return StatusCode::SUCCESS;
00631
00632 }
00633
00634
00635 std::string ToolSvc::nameTool( const std::string& toolname,
00636 const IInterface* parent )
00637
00638 {
00639
00640 std::string fullname = "";
00641 if ( parent == 0 ) { return this->name() + "." + toolname; }
00642
00643
00644 IInterface* cparent = const_cast<IInterface*>( parent ) ;
00645
00646 INamedInterface* _p = 0 ;
00647 StatusCode sc = cparent->queryInterface( INamedInterface::interfaceID() , pp_cast<void>(&_p) ) ;
00648 if ( sc.isSuccess() )
00649 {
00650 fullname = _p->name() + "." + toolname ;
00651 _p->release() ;
00652 return fullname ;
00653 }
00654
00655 MsgStream log ( msgSvc(), name() );
00656 log << MSG::ERROR
00657 << "Private Tools only allowed for components implementing INamedInterface"
00658 << endmsg;
00659
00660 return "." + toolname ;
00661 }
00662
00663
00664 bool ToolSvc::existsTool( const std::string& fullname) const
00665
00666 {
00667 for ( ListTools::const_iterator it = m_instancesTools.begin();
00668 it != m_instancesTools.end(); ++it ) {
00669 if ( (*it)->name() == fullname ) { return true; }
00670 }
00671 return false;
00672 }
00673
00674
00675 StatusCode ToolSvc::finalizeTool( IAlgTool* itool ) const
00676
00677 {
00678
00679
00680 const std::string toolName = itool->name();
00681 StatusCode sc;
00682
00683
00684 try { sc = itool->sysFinalize(); }
00685
00686
00687 catch ( const GaudiException & Exception )
00688 {
00689 MsgStream msg ( msgSvc(), name() );
00690 msg << MSG::ERROR
00691 << "GaudiException with tag=" << Exception.tag()
00692 << " caught whilst finalizing tool '" << toolName << "'" << endmsg
00693 << Exception << endmsg;
00694 sc = StatusCode::FAILURE;
00695 }
00696 catch( const std::exception & Exception )
00697 {
00698 MsgStream msg ( msgSvc(), name() );
00699 msg << MSG::ERROR
00700 << "Standard std::exception caught whilst finalizing tool '"
00701 << toolName << "'" << endmsg << Exception.what() << endmsg;
00702 sc = StatusCode::FAILURE;
00703 }
00704 catch (...)
00705 {
00706 MsgStream msg ( msgSvc(), name() );
00707 msg << MSG::ERROR
00708 << "UNKNOWN Exception caught whilst finalizing tool '"
00709 << toolName << "'" << endmsg;
00710 sc = StatusCode::FAILURE;
00711 }
00712
00713 return sc;
00714
00715 }
00716
00717
00718 unsigned long ToolSvc::totalToolRefCount( const ToolSvc::ListTools& toolList ) const
00719
00720 {
00721 unsigned long count = 0;
00722 for ( ListTools::const_iterator iTool = toolList.begin();
00723 iTool != toolList.end(); ++iTool ) {
00724 count += refCountTool( *iTool );
00725 }
00726 return count;
00727 }
00728
00729
00730 unsigned long ToolSvc::totalToolRefCount() const
00731
00732 {
00733 return totalToolRefCount( m_instancesTools );
00734 }
00735
00736 unsigned long ToolSvc::minimumToolRefCount() const
00737
00738 {
00739 unsigned long count = 0;
00740 if ( m_instancesTools.size() > 0 ) {
00741 ListTools::const_iterator iTool = m_instancesTools.begin();
00742
00743 count = refCountTool( *iTool );
00744
00745 for( ++iTool; iTool != m_instancesTools.end(); ++iTool ) {
00746 count = std::min( count, refCountTool( *iTool ) );
00747 }
00748 }
00749 return count;
00750 }
00751
00752 void ToolSvc::registerObserver(IToolSvc::Observer* obs) {
00753 if ( 0 == obs )
00754 throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
00755 m_observers.push_back(obs);
00756 }
00757
00758 void ToolSvc::unRegisterObserver(IToolSvc::Observer* obs) {
00759 std::vector<IToolSvc::Observer*>::iterator i =
00760 find(m_observers.begin(),m_observers.end(),obs);
00761 if (i!=m_observers.end()) m_observers.erase(i);
00762 }
00763
00764
00765 StatusCode
00766 ToolSvc::start()
00767
00768 {
00769
00770 MsgStream log( msgSvc(), name() );
00771 log << MSG::DEBUG << "START transition for AlgTools" << endmsg;
00772
00773 bool fail(false);
00774 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00775 iTool != m_instancesTools.end(); ++iTool ) {
00776 log << MSG::VERBOSE << (*iTool)->name() << "::start()" << endmsg;
00777
00778 if (!(*iTool)->sysStart().isSuccess()) {
00779 fail = true;
00780 log << MSG::ERROR << (*iTool)->name() << " failed to start()" << endmsg;
00781 }
00782
00783 }
00784
00785 if (fail) {
00786 log << MSG::ERROR << "One or more AlgTools failed to start()" << endmsg;
00787 return StatusCode::FAILURE;
00788 } else {
00789 return StatusCode::SUCCESS;
00790 }
00791
00792 }
00793
00794
00795 StatusCode
00796 ToolSvc::stop()
00797
00798 {
00799
00800 MsgStream log( msgSvc(), name() );
00801 log << MSG::DEBUG << "STOP transition for AlgTools" << endmsg;
00802
00803 bool fail(false);
00804 for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00805 iTool != m_instancesTools.end(); ++iTool ) {
00806 log << MSG::VERBOSE << (*iTool)->name() << "::stop()" << endmsg;
00807
00808 if (!(*iTool)->sysStop().isSuccess()) {
00809 fail = true;
00810 log << MSG::ERROR << (*iTool)->name() << " failed to stop()" << endmsg;
00811 }
00812
00813 }
00814
00815 if (fail) {
00816 log << MSG::ERROR << "One or more AlgTools failed to stop()" << endmsg;
00817 return StatusCode::FAILURE;
00818 } else {
00819 return StatusCode::SUCCESS;
00820 }
00821
00822 }