Gaudi Framework, version v23r2

Home   Generated: Thu Jun 28 2012

ToolSvc.cpp

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

Generated at Thu Jun 28 2012 23:27:17 for Gaudi Framework, version v23r2 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004