Gaudi Framework, version v22r0

Home   Generated: 9 Feb 2011

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

Generated at Wed Feb 9 16:25:04 2011 for Gaudi Framework, version v22r0 by Doxygen version 1.6.2 written by Dimitri van Heesch, © 1997-2004