![]() |
|
|
Generated: 8 Jan 2009 |
00001 // $Id: ToolSvc.cpp,v 1.39 2008/11/02 14:17:13 marcocle Exp $ 00002 00003 // Include Files 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 // Instantiation of a static factory class used by clients to create 00023 // instances of this service 00024 DECLARE_SERVICE_FACTORY(ToolSvc) 00025 00026 using ROOT::Reflex::PluginService; 00027 namespace bl = boost::lambda; 00028 00029 //------------------------------------------------------------------------------ 00030 ToolSvc::ToolSvc( const std::string& name, ISvcLocator* svc ) 00031 //------------------------------------------------------------------------------ 00032 : Service(name, svc), 00033 m_pHistorySvc(0) 00034 { } 00035 00036 //------------------------------------------------------------------------------ 00037 ToolSvc::~ToolSvc() 00038 //------------------------------------------------------------------------------ 00039 { 00040 00041 } 00042 00043 //------------------------------------------------------------------------------ 00044 StatusCode ToolSvc::initialize() 00045 //------------------------------------------------------------------------------ 00046 { 00047 00048 // initialize the Service Base class 00049 StatusCode status = Service::initialize(); 00050 if ( status.isFailure() ) 00051 { 00052 MsgStream log( msgSvc(), name() ); 00053 log << MSG::ERROR << "Unable to initialize the Service" << endreq; 00054 return status; 00055 } 00056 00057 // set my own (ToolSvc) properties via the jobOptionService 00058 if (setProperties().isFailure()) { 00059 MsgStream log( msgSvc(), name() ); 00060 log << MSG::ERROR << "Unable to set base properties" << endreq; 00061 return StatusCode::FAILURE; 00062 } 00063 00064 return status; 00065 } 00066 00067 //------------------------------------------------------------------------------ 00068 StatusCode ToolSvc::finalize() 00069 //------------------------------------------------------------------------------ 00070 { 00071 // Finalize and delete all left-over tools. Normally all tools created with 00072 // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor). 00073 // Several cases need to be covered: 00074 // 1) Simple dependencies: no circular dependencies between tools, 00075 // and tools not using other tools 00076 // 2) Tools-using-tools (but no circular dependencies) 00077 // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm) 00078 // b) release() is called in the tool destructor (e.g. via ToolHandle) 00079 // 3) Circular dependencies between tools 00080 // a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm) 00081 // b) release() is called in the tool destructor (e.g. via ToolHandle) 00082 // 4) In addition to each of the above cases, refCounting of a particular tool 00083 // might not have been done correctly in the code. Typically release() 00084 // is not called, so we are left with a too high refCount. 00085 // What to do with those, and how to avoid a crash while handling them... 00086 00095 MsgStream log( msgSvc(), name() ); 00096 ListTools finalizedTools; // list of tools that have been finalized 00097 log << MSG::INFO << "Removing all tools created by ToolSvc" << endreq; 00098 00099 // Print out list of tools 00100 log << MSG::DEBUG << " Tool List : "; 00101 for ( ListTools::const_iterator iTool = m_instancesTools.begin(); 00102 iTool != m_instancesTools.end(); ++iTool ) { 00103 log << (*iTool)->name() << ":" << refCountTool( *iTool ) << " "; 00104 } 00105 log << endreq; 00106 00107 // 00108 // first pass: Finalize all tools (but don't delete them) 00109 // 00122 bool fail(false); 00123 size_t toolCount = m_instancesTools.size(); 00124 unsigned long startRefCount = 0; 00125 unsigned long endRefCount = totalToolRefCount(); 00126 unsigned long startMinRefCount = 0; 00127 unsigned long endMinRefCount = minimumToolRefCount(); 00128 while ( toolCount > 0 && 00129 endRefCount > 0 && 00130 (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) { 00131 if ( endMinRefCount != startMinRefCount ) { 00132 log << MSG::DEBUG << toolCount << " tools left to finalize. Summed refCounts: " 00133 << endRefCount << endreq; 00134 log << MSG::DEBUG << "Will finalize tools with refCount <= " 00135 << endMinRefCount << endreq; 00136 } 00137 startMinRefCount = endMinRefCount; 00138 startRefCount = endRefCount; 00139 unsigned long maxLoop = toolCount + 1; 00140 while ( --maxLoop > 0 && m_instancesTools.size() > 0 ) { 00141 IAlgTool* pTool = m_instancesTools.back(); 00142 // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop 00143 m_instancesTools.pop_back(); 00144 unsigned long count = refCountTool( pTool ); 00145 // cache tool name 00146 std::string toolName = pTool->name(); 00147 if ( count <= startMinRefCount ) { 00148 log << MSG::DEBUG << " Performing finalization of " << toolName 00149 << " (refCount " << count << ")" << endreq; 00150 // finalize of one tool may trigger a release of another tool 00151 // pTool->sysFinalize().ignore(); 00152 if (!finalizeTool(pTool).isSuccess()) fail = true; 00153 // postpone deletion 00154 finalizedTools.push_back(pTool); 00155 } else { 00156 // Place back in list to try again later 00157 // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool 00158 log << MSG::DEBUG << " Delaying finalization of " << toolName 00159 << " (refCount " << count << ")" << endreq; 00160 m_instancesTools.push_front(pTool); 00161 } 00162 } // end of inner loop 00163 toolCount = m_instancesTools.size(); 00164 endRefCount = totalToolRefCount(); 00165 endMinRefCount = minimumToolRefCount(); 00166 }; // end of outer loop 00167 00168 // 00169 // Second pass: Delete all finalized tools 00170 // 00171 // Delete in the order of increasing number of refCounts. 00172 // Loop over tools in the same order as the order in which they were finalized. 00173 // All tools in the list of finalized tools are no longer in the instancesTools list. 00174 // If a tool destructor calls releaseTool() on another tool, this will have no 00175 // effect on the 'other tool' if this 'other tool' is in the list of finalized tools. 00176 // If this 'other tool' is still in the instancesTools list, it may trigger finalization 00177 // (in releaseTool()), deletion and removal from the instancesTools list. 00178 // Therefore, the check on non-finalised tools should happen *after* the deletion 00179 // of the finalized tools. 00180 log << MSG::DEBUG << "Deleting " << finalizedTools.size() << " finalized tools" << endreq; 00181 unsigned long maxLoop = totalToolRefCount( finalizedTools ) + 1; 00182 while ( --maxLoop > 0 && finalizedTools.size() > 0 ) { 00183 IAlgTool* pTool = finalizedTools.front(); 00184 finalizedTools.pop_front(); 00185 unsigned long count = refCountTool( pTool ); 00186 if ( count == 1 ) { 00187 log << MSG::DEBUG << " Performing deletion of " << pTool->name() << endreq; 00188 } else { 00189 log << MSG::VERBOSE << " Delaying deletion of " << pTool->name() 00190 << " (refCount " << count << ")" << endreq; 00191 // Put it back at the end of the list if refCount still not zero 00192 finalizedTools.push_back(pTool); 00193 } 00194 // do a forced release 00195 pTool->release(); 00196 } 00197 00198 // Error if by now not all tools are properly finalised 00199 if ( !m_instancesTools.empty() ) { 00200 log << MSG::ERROR << "Unable to finalize and delete the following tools : "; 00201 for ( ListTools::const_iterator iTool = m_instancesTools.begin(); 00202 iTool != m_instancesTools.end(); ++iTool ) { 00203 log << (*iTool)->name() << ": " << refCountTool( *iTool ) << " "; 00204 } 00205 log << endreq; 00206 } 00207 00208 // by now, all tools should be deleted and removed. 00209 if ( finalizedTools.size() > 0 ) { 00210 log << MSG::ERROR << "Failed to delete the following " << finalizedTools.size() 00211 << " finalized tools. Bug in ToolSvc::finalize()?: "; 00212 for ( ListTools::const_iterator iTool = finalizedTools.begin(); 00213 iTool != finalizedTools.end(); ++iTool ) { 00214 log << (*iTool)->name() << ": " << refCountTool( *iTool ) << " "; 00215 } 00216 log << endreq; 00217 } 00218 00219 if ( 0 != m_pHistorySvc ) { 00220 m_pHistorySvc->release(); 00221 } 00222 00223 // Finalize this specific service 00224 if (! Service::finalize().isSuccess() || fail) { 00225 return StatusCode::FAILURE; 00226 } else { 00227 return StatusCode::SUCCESS; 00228 } 00229 00230 00231 } 00232 00233 //------------------------------------------------------------------------------ 00234 StatusCode ToolSvc::queryInterface( const InterfaceID& riid, void** ppvInterface ) 00235 //------------------------------------------------------------------------------ 00236 { 00237 if ( IID_IToolSvc == riid ) { 00238 *ppvInterface = (IToolSvc*)this; 00239 } 00240 else { 00241 // Interface is not directly available: try out a base class 00242 return Service::queryInterface(riid, ppvInterface); 00243 } 00244 addRef(); 00245 return StatusCode::SUCCESS; 00246 } 00247 00248 // =================================================================================== 00252 // =================================================================================== 00253 namespace 00254 { 00255 const std::string s_PUBLIC = ":PUBLIC" ; 00256 } 00257 00258 //------------------------------------------------------------------------------ 00259 StatusCode ToolSvc::retrieve ( const std::string& tooltype , 00260 const InterfaceID& iid , 00261 IAlgTool*& tool , 00262 const IInterface* parent , 00263 bool createIf ) 00264 //------------------------------------------------------------------------------ 00265 { 00266 00267 // protect against empty type 00268 if ( tooltype.empty() ) { 00269 MsgStream log( msgSvc(), name() ); 00270 log << MSG::ERROR << "retrieve(): No Tool Type/Name given" << endreq; 00271 return StatusCode::FAILURE; 00272 } 00273 00274 { 00275 // check for tools, which by name is required to be public: 00276 const std::string::size_type pos = tooltype.find ( s_PUBLIC ) ; 00277 if ( std::string::npos != pos ) 00278 { 00279 // set parent for PUBLIC tool 00280 parent = this ; 00281 return retrieve ( std::string( tooltype , 0 , pos ) , 00282 iid , tool , parent , createIf ) ; 00283 } 00284 } 00285 00286 const std::string::size_type pos = tooltype.find('/'); 00287 if( std::string::npos == pos ) 00288 { return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );} 00289 const std::string newtype ( tooltype , 0 , pos ) ; 00290 const std::string newname ( tooltype , pos + 1 , std::string::npos ) ; 00291 return retrieve ( newtype , newname , iid , tool , parent , createIf ) ; 00292 } 00293 00294 // =================================================================================== 00295 00296 //------------------------------------------------------------------------------ 00297 StatusCode ToolSvc::retrieve ( const std::string& tooltype , 00298 const std::string& toolname , 00299 const InterfaceID& iid , 00300 IAlgTool*& tool , 00301 const IInterface* parent , 00302 bool createIf ) 00303 //------------------------------------------------------------------------------ 00304 { 00305 MsgStream log( msgSvc(), name() ); 00306 00307 // check the applicability of another method: 00308 // ignore the provided name if it is empty or the type contains a name 00309 if( toolname.empty() || (std::string::npos != tooltype.find('/')) ) 00310 { return retrieve ( tooltype , iid , tool , parent , createIf ) ; } 00311 00312 { 00313 // check for tools, which by name is required to be public: 00314 const std::string::size_type pos = toolname.find ( s_PUBLIC ) ; 00315 if ( std::string::npos != pos ) 00316 { 00317 // set parent for PUBLIC tool 00318 parent = this ; 00319 return retrieve ( tooltype , std::string( toolname , 0 , pos ) , 00320 iid , tool , parent , createIf ) ; 00321 } 00322 } 00323 00324 IAlgTool* itool = 0; 00325 StatusCode sc(StatusCode::FAILURE); 00326 00327 tool = 0; 00328 00329 // If parent is not specified it means it is the ToolSvc itself 00330 if( 0 == parent ) { 00331 parent = this; 00332 } 00333 const std::string fullname = nameTool( toolname, parent ); 00334 00335 // Find tool in list of those already existing, and tell its 00336 // interface that it has been used one more time 00337 ListTools::const_iterator it; 00338 for( it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it ) { 00339 if( (*it)->name() == fullname ) { 00340 log << MSG::DEBUG << "Retrieved tool " << toolname << endreq; 00341 itool = *it; 00342 break; 00343 } 00344 } 00345 00346 if ( 0 == itool ) { 00347 // Instances of this tool do not exist, create an instance if desired 00348 // otherwise return failure 00349 if( !createIf ) { 00350 log << MSG::WARNING << "Tool " << toolname 00351 << " not found and creation not requested" << endreq; 00352 return sc; 00353 } 00354 else { 00355 sc = create( tooltype, toolname, parent, itool ); 00356 if ( sc.isFailure() ) { return sc; } 00357 } 00358 } 00359 00360 // Get the right interface of it 00361 sc = itool->queryInterface( iid, (void**)&tool); 00362 if( sc.isFailure() ) { 00363 log << MSG::ERROR << "Tool " << toolname 00364 << " either does not implement the correct interface, or its version is incompatible" 00365 << endreq; 00366 return sc; 00367 } 00371 if (!m_observers.empty()) { 00372 std::for_each( m_observers.begin(), 00373 m_observers.end(), 00374 bl::bind(&IToolSvc::Observer::onRetrieve, 00375 bl::_1, 00376 itool)); 00377 } 00378 00379 return sc; 00380 } 00381 //------------------------------------------------------------------------------ 00382 std::vector<std::string> ToolSvc::getInstances( const std::string& toolType ) 00383 //------------------------------------------------------------------------------ 00384 { 00385 00386 std::vector<std::string> tools; 00387 00388 ListTools::const_iterator it; 00389 for (it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it) { 00390 if ((*it)->type() == toolType) { 00391 tools.push_back( (*it)->name() ); 00392 } 00393 } 00394 00395 return tools; 00396 00397 } 00398 //------------------------------------------------------------------------------ 00399 StatusCode ToolSvc::releaseTool( IAlgTool* tool ) 00400 //------------------------------------------------------------------------------ 00401 { 00402 StatusCode sc(StatusCode::SUCCESS); 00403 // test if tool is in known list (protect trying to access a previously deleted tool) 00404 if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(), 00405 m_instancesTools.rend(), 00406 tool ) ) { 00407 unsigned long count = refCountTool(tool); 00408 if ( count == 1 ) { 00409 MsgStream log( msgSvc(), name() ); 00410 // finalize the tool 00411 00412 if ( Gaudi::StateMachine::OFFLINE == m_targetState ) { 00413 // We are being called during ToolSvc::finalize() 00414 // message format matches the one in ToolSvc::finalize() 00415 log << MSG::DEBUG << " Performing finalization of " << tool->name() 00416 << " (refCount " << count << ")" << endreq; 00417 // message format matches the one in ToolSvc::finalize() 00418 log << MSG::DEBUG << " Performing deletion of " << tool->name() << endreq; 00419 } else { 00420 log << MSG::DEBUG << "Performing finalization and deletion of " << tool->name() << endreq; 00421 } 00422 sc = finalizeTool(tool); 00423 // remove from known tools... 00424 m_instancesTools.remove(tool); 00425 } 00426 tool->release(); 00427 } 00428 00429 return sc; 00430 } 00431 00432 //------------------------------------------------------------------------------ 00433 StatusCode ToolSvc::create(const std::string& tooltype, 00434 const IInterface* parent, 00435 IAlgTool*& tool) 00436 //------------------------------------------------------------------------------ 00437 { 00438 const std::string & toolname = tooltype; 00439 return create( tooltype, toolname, parent, tool); 00440 } 00441 00442 namespace { 00445 class ToolCreateGuard { 00446 public: 00447 ToolCreateGuard(ToolSvc::ListTools &listTools): 00448 m_list(listTools), 00449 m_tool(0) 00450 {} 00452 void set(IAlgTool* tool) { 00453 if (m_tool) { // remove previous content 00454 m_list.remove(m_tool); 00455 delete m_tool; 00456 } 00457 if (tool) { // set new content 00458 m_tool = tool; 00459 m_list.push_back(m_tool); 00460 } 00461 } 00462 ToolCreateGuard& operator=(IAlgTool* tool) { 00463 set(tool); 00464 return *this; 00465 } 00467 IAlgTool* get() { 00468 return m_tool; 00469 } 00470 IAlgTool& operator*() const { 00471 assert(m_tool != 0); 00472 return *m_tool; 00473 } 00474 IAlgTool* operator->() const { 00475 assert(m_tool != 0); 00476 return m_tool; 00477 } 00479 IAlgTool* release() { 00480 IAlgTool* tool = m_tool; 00481 m_tool = 0; 00482 return tool; 00483 } 00485 ~ToolCreateGuard(){ 00486 set(0); 00487 } 00488 private: 00490 ToolSvc::ListTools& m_list; 00492 IAlgTool* m_tool; 00493 }; 00494 } 00495 //------------------------------------------------------------------------------ 00496 StatusCode ToolSvc::create(const std::string& tooltype, 00497 const std::string& toolname, 00498 const IInterface* parent, 00499 IAlgTool*& tool) 00500 //------------------------------------------------------------------------------ 00501 { 00502 MsgStream log( msgSvc(), name() ); 00503 // protect against empty type 00504 if ( tooltype.empty() ) { 00505 log << MSG::ERROR << "create(): No Tool Type given" << endreq; 00506 return StatusCode::FAILURE; 00507 } 00508 00509 // If parent has not been specified, assume it is the ToolSvc 00510 if ( 0 == parent ) parent = this; 00511 00512 tool = 0; 00513 // Automatically deletes the tool if not explicitly kept (i.e. on success). 00514 // The tool is removed from the list of known tools too. 00515 ToolCreateGuard toolguard(m_instancesTools); 00516 00517 // Check if the tool already exist : this should never happen 00518 const std::string fullname = nameTool(toolname, parent); 00519 if( existsTool( fullname ) ) { 00520 log << MSG::ERROR << "Tool " << fullname << " already exists" << endreq; 00521 return StatusCode::FAILURE; 00522 } 00523 // instantiate the tool using the factory 00524 try { 00525 toolguard = PluginService::Create<IAlgTool*>(tooltype, tooltype, fullname, parent); 00526 if ( ! toolguard.get() ){ 00527 log << MSG::ERROR 00528 << "Cannot create tool " << tooltype << " (No factory found)" << endreq; 00529 return StatusCode::FAILURE; 00530 } 00531 } 00532 catch ( const GaudiException& Exception ) { 00533 // (1) perform the printout of message 00534 MsgStream log ( msgSvc() , name() ); 00535 log << MSG::FATAL << "Exception with tag=" << Exception.tag() 00536 << " is caught whilst instantiating tool '" << tooltype << "'" << endreq; 00537 // (2) print the exception itself 00538 // (NB! - GaudiException is a linked list of all "previous exceptions") 00539 log << MSG::FATAL << Exception << endreq; 00540 return StatusCode::FAILURE; 00541 } 00542 catch( const std::exception& Exception ) { 00543 // (1) perform the printout of message 00544 MsgStream log ( msgSvc() , name() ); 00545 log << MSG::FATAL 00546 << "Standard std::exception is caught whilst instantiating tool '" 00547 << tooltype << "'" << endreq; 00548 // (2) print the exception itself 00549 // (NB! - GaudiException is a linked list of all "previous exceptions") 00550 log << MSG::FATAL << Exception.what() << endreq; 00551 return StatusCode::FAILURE; 00552 } 00553 catch(...) { 00554 // (1) perform the printout 00555 MsgStream log ( msgSvc() , name() ); 00556 log << MSG::FATAL << "UNKNOWN Exception is caught whilst instantiating tool '" 00557 << tooltype << "'" << endreq; 00558 return StatusCode::FAILURE; 00559 } 00560 log << MSG::VERBOSE << "Created tool " << tooltype << "/" << fullname << endreq; 00561 00562 // Since only AlgTool has the setProperties() method it is necessary to cast 00563 // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions 00564 // service 00565 AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get()); 00566 if ( mytool != 0 ) { 00567 StatusCode sc = mytool->setProperties(); 00568 if ( sc.isFailure() ) { 00569 MsgStream log ( msgSvc() , name() ); 00570 log << MSG::ERROR << "Error setting properties for tool '" 00571 << fullname << "'" << endreq; 00572 return sc; 00573 } 00574 } 00575 00576 // Initialize the Tool 00577 StatusCode sc (StatusCode::FAILURE,true); 00578 try { sc = toolguard->sysInitialize(); } 00579 00580 // Catch any exceptions 00581 catch ( const GaudiException & Exception ) 00582 { 00583 MsgStream msg ( msgSvc(), name() ); 00584 msg << MSG::ERROR 00585 << "GaudiException with tag=" << Exception.tag() 00586 << " caught whilst initializing tool '" << fullname << "'" << endreq 00587 << Exception << endreq; 00588 return StatusCode::FAILURE; 00589 } 00590 catch( const std::exception & Exception ) 00591 { 00592 MsgStream msg ( msgSvc(), name() ); 00593 msg << MSG::ERROR 00594 << "Standard std::exception caught whilst initializing tool '" 00595 << fullname << "'" << endreq << Exception.what() << endreq; 00596 return StatusCode::FAILURE; 00597 } 00598 catch (...) 00599 { 00600 MsgStream msg ( msgSvc(), name() ); 00601 msg << MSG::ERROR 00602 << "UNKNOWN Exception caught whilst initializing tool '" 00603 << fullname << "'" << endreq; 00604 return StatusCode::FAILURE; 00605 } 00606 00607 // Status of tool intialization 00608 if ( sc.isFailure() ) { 00609 MsgStream log( msgSvc(), name() ); 00610 log << MSG::ERROR << "Error initializing tool '" << fullname << "'" << endreq; 00611 return sc; 00612 } 00613 00614 // The tool has been successfully created and initialized, 00615 // so we the guard can be released 00616 tool = toolguard.release(); 00617 00621 if (!m_observers.empty()) { 00622 std::for_each( m_observers.begin(), 00623 m_observers.end(), 00624 bl::bind(&IToolSvc::Observer::onCreate, 00625 bl::_1, 00626 tool)); 00627 } 00628 // TODO: replace by generic callback 00629 // Register the tool with the HistorySvc 00630 if (m_pHistorySvc != 0 || 00631 service("HistorySvc",m_pHistorySvc,false).isSuccess() ) { 00632 m_pHistorySvc->registerAlgTool(*tool).ignore(); 00633 } 00634 00635 return StatusCode::SUCCESS; 00636 00637 } 00638 00639 //------------------------------------------------------------------------------ 00640 std::string ToolSvc::nameTool( const std::string& toolname, 00641 const IInterface* parent ) 00642 //------------------------------------------------------------------------------ 00643 { 00644 00645 std::string fullname = ""; 00646 if ( parent == 0 ) { return this->name() + "." + toolname; } // RETURN 00647 00648 00649 IInterface* cparent = const_cast<IInterface*>( parent ) ; 00650 // check that parent has a name! 00651 INamedInterface* _p = 0 ; 00652 StatusCode sc = cparent->queryInterface( INamedInterface::interfaceID() , pp_cast<void>(&_p) ) ; 00653 if ( sc.isSuccess() ) 00654 { 00655 fullname = _p->name() + "." + toolname ; 00656 _p->release() ; 00657 return fullname ; // RETURN 00658 } 00659 00660 MsgStream log ( msgSvc(), name() ); 00661 log << MSG::ERROR 00662 << "Private Tools only allowed for INamedInterfaces" 00663 << endreq; 00664 // 00665 return "." + toolname ; 00666 } 00667 00668 //------------------------------------------------------------------------------ 00669 bool ToolSvc::existsTool( const std::string& fullname) const 00670 //------------------------------------------------------------------------------ 00671 { 00672 for ( ListTools::const_iterator it = m_instancesTools.begin(); 00673 it != m_instancesTools.end(); ++it ) { 00674 if ( (*it)->name() == fullname ) { return true; } 00675 } 00676 return false; 00677 } 00678 00679 //------------------------------------------------------------------------------ 00680 StatusCode ToolSvc::finalizeTool( IAlgTool* itool ) const 00681 //------------------------------------------------------------------------------ 00682 { 00683 00684 // Cache tool name in case of errors 00685 const std::string toolName = itool->name(); 00686 StatusCode sc; 00687 00688 // Finalise the tool inside a try block 00689 try { sc = itool->sysFinalize(); } 00690 00691 // Catch any exceptions 00692 catch ( const GaudiException & Exception ) 00693 { 00694 MsgStream msg ( msgSvc(), name() ); 00695 msg << MSG::ERROR 00696 << "GaudiException with tag=" << Exception.tag() 00697 << " caught whilst finalizing tool '" << toolName << "'" << endreq 00698 << Exception << endreq; 00699 sc = StatusCode::FAILURE; 00700 } 00701 catch( const std::exception & Exception ) 00702 { 00703 MsgStream msg ( msgSvc(), name() ); 00704 msg << MSG::ERROR 00705 << "Standard std::exception caught whilst finalizing tool '" 00706 << toolName << "'" << endreq << Exception.what() << endreq; 00707 sc = StatusCode::FAILURE; 00708 } 00709 catch (...) 00710 { 00711 MsgStream msg ( msgSvc(), name() ); 00712 msg << MSG::ERROR 00713 << "UNKNOWN Exception caught whilst finalizing tool '" 00714 << toolName << "'" << endreq; 00715 sc = StatusCode::FAILURE; 00716 } 00717 00718 return sc; 00719 00720 } 00721 00722 //------------------------------------------------------------------------------ 00723 unsigned long ToolSvc::totalToolRefCount( const ToolSvc::ListTools& toolList ) const 00724 //------------------------------------------------------------------------------ 00725 { 00726 unsigned long count = 0; 00727 for ( ListTools::const_iterator iTool = toolList.begin(); 00728 iTool != toolList.end(); ++iTool ) { 00729 count += refCountTool( *iTool ); 00730 } 00731 return count; 00732 } 00733 00734 //------------------------------------------------------------------------------ 00735 unsigned long ToolSvc::totalToolRefCount() const 00736 //------------------------------------------------------------------------------ 00737 { 00738 return totalToolRefCount( m_instancesTools ); 00739 } 00740 //------------------------------------------------------------------------------ 00741 unsigned long ToolSvc::minimumToolRefCount() const 00742 //------------------------------------------------------------------------------ 00743 { 00744 unsigned long count = 0; 00745 if ( m_instancesTools.size() > 0 ) { 00746 ListTools::const_iterator iTool = m_instancesTools.begin(); 00747 // start with first 00748 count = refCountTool( *iTool ); 00749 // then compare the others 00750 for( ++iTool; iTool != m_instancesTools.end(); ++iTool ) { 00751 count = std::min( count, refCountTool( *iTool ) ); 00752 } 00753 } 00754 return count; 00755 } 00756 00757 void ToolSvc::registerObserver(IToolSvc::Observer* obs) { 00758 if ( 0 == obs ) 00759 throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE ); 00760 m_observers.push_back(obs); 00761 } 00762 00763 void ToolSvc::unRegisterObserver(IToolSvc::Observer* obs) { 00764 std::vector<IToolSvc::Observer*>::iterator i = 00765 find(m_observers.begin(),m_observers.end(),obs); 00766 if (i!=m_observers.end()) m_observers.erase(i); 00767 }