| # Gaudi Framework, version v20r2
Generated: 18 Jul 2008

- Main Page
- Namespaces
- Classes
- Files
- Directories
- Related Pages

- Search for |

- File List
- File Members

# ToolSvc.cpp

Go to the documentation of this file.

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