Gaudi Framework, version v21r8

Home   Generated: 17 Mar 2010

ToolSvc.cpp

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

Generated at Wed Mar 17 18:06:50 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004