Gaudi Framework, version v22r4

Home   Generated: Fri Sep 2 2011

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()) fail = true;
00157         // postpone deletion
00158         finalizedTools.push_back(pTool);
00159       } else {
00160         // Place back in list to try again later
00161         // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
00162         ON_DEBUG debug() << "  Delaying   finalization of " << toolName
00163                          << " (refCount " << count << ")" << endmsg;
00164         m_instancesTools.push_front(pTool);
00165       }
00166     } // end of inner loop
00167     toolCount = m_instancesTools.size();
00168     endRefCount = totalToolRefCount();
00169     endMinRefCount = minimumToolRefCount();
00170   }; // end of outer loop
00171 
00172   //
00173   // Second pass: Delete all finalized tools
00174   //
00175   // Delete in the order of increasing number of refCounts.
00176   // Loop over tools in the same order as the order in which they were finalized.
00177   // All tools in the list of finalized tools are no longer in the instancesTools list.
00178   // If a tool destructor calls releaseTool() on another tool, this will have no
00179   // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
00180   // If this 'other tool' is still in the instancesTools list, it may trigger finalization
00181   // (in releaseTool()), deletion and removal from the instancesTools list.
00182   // Therefore, the check on non-finalised tools should happen *after* the deletion
00183   // of the finalized tools.
00184   ON_DEBUG debug() << "Deleting " << finalizedTools.size() << " finalized tools" << endmsg;
00185   unsigned long maxLoop = totalToolRefCount( finalizedTools ) + 1;
00186   while ( --maxLoop > 0 && finalizedTools.size() > 0 ) {
00187     IAlgTool* pTool = finalizedTools.front();
00188     finalizedTools.pop_front();
00189     unsigned long count = refCountTool( pTool );
00190     if ( count == 1 ) {
00191       ON_DEBUG debug() << "  Performing deletion of " << pTool->name() << endmsg;
00192     } else {
00193       ON_VERBOSE verbose() << "  Delaying   deletion of " << pTool->name()
00194           << " (refCount " << count << ")" << endmsg;
00195       // Put it back at the end of the list if refCount still not zero
00196       finalizedTools.push_back(pTool);
00197     }
00198     // do a forced release
00199     pTool->release();
00200   }
00201 
00202   // Error if by now not all tools are properly finalised
00203   if ( !m_instancesTools.empty() ) {
00204     error() << "Unable to finalize and delete the following tools : ";
00205     for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00206           iTool != m_instancesTools.end(); ++iTool ) {
00207       error() << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
00208     }
00209     error() << endmsg;
00210   }
00211 
00212   // by now, all tools should be deleted and removed.
00213   if ( finalizedTools.size() > 0 ) {
00214     error() << "Failed to delete the following " <<  finalizedTools.size()
00215             << " finalized tools. Bug in ToolSvc::finalize()?: ";
00216     for ( ListTools::const_iterator iTool = finalizedTools.begin();
00217           iTool != finalizedTools.end(); ++iTool ) {
00218       error() << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
00219     }
00220     error() << endmsg;
00221   }
00222 
00223   if ( 0 != m_pHistorySvc ) {
00224     m_pHistorySvc->release();
00225   }
00226 
00227   // Finalize this specific service
00228   if (! Service::finalize().isSuccess() || fail) {
00229     return StatusCode::FAILURE;
00230   } else {
00231     return StatusCode::SUCCESS;
00232   }
00233 
00234 
00235 }
00236 
00237 // ===================================================================================
00241 // ===================================================================================
00242 namespace
00243 {
00244   const std::string s_PUBLIC = ":PUBLIC" ;
00245 }
00246 
00247 //------------------------------------------------------------------------------
00248 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
00249                                const InterfaceID& iid      ,
00250                                IAlgTool*&         tool     ,
00251                                const IInterface*  parent   ,
00252                                bool               createIf )
00253 //------------------------------------------------------------------------------
00254 {
00255 
00256   // protect against empty type
00257   if ( tooltype.empty() ) {
00258     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   }
00278   const std::string newtype ( tooltype ,       0 , pos               ) ;
00279   const std::string newname ( tooltype , pos + 1 , std::string::npos ) ;
00280   return retrieve ( newtype , newname , iid , tool , parent , createIf ) ;
00281 }
00282 
00283 // ===================================================================================
00284 
00285 //------------------------------------------------------------------------------
00286 StatusCode ToolSvc::retrieve ( const std::string& tooltype ,
00287                                const std::string& toolname ,
00288                                const InterfaceID& iid      ,
00289                                IAlgTool*&         tool     ,
00290                                const IInterface*  parent   ,
00291                                bool               createIf )
00292   //------------------------------------------------------------------------------
00293 {
00294   // check the applicability of another method:
00295   // ignore the provided name if it is empty or the type contains a name
00296   if( toolname.empty() || (std::string::npos != tooltype.find('/')) )
00297   { return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
00298 
00299   {
00300     // check for tools, which by name is required to be public:
00301     const std::string::size_type pos = toolname.find ( s_PUBLIC ) ;
00302     if ( std::string::npos != pos )
00303     {
00304       // set parent for PUBLIC tool
00305       parent = this ;
00306       return retrieve ( tooltype , std::string( toolname , 0 , pos ) ,
00307                         iid , tool , parent , createIf ) ;
00308     }
00309   }
00310 
00311   IAlgTool* itool = 0;
00312   StatusCode sc(StatusCode::FAILURE);
00313 
00314   tool = 0;
00315 
00316   // If parent is not specified it means it is the ToolSvc itself
00317   if( 0 == parent ) {
00318     parent = this;
00319   }
00320   const std::string fullname = nameTool( toolname, parent );
00321 
00322   // Find tool in list of those already existing, and tell its
00323   // interface that it has been used one more time
00324   ListTools::const_iterator it;
00325   for( it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it ) {
00326     if( (*it)->name() == fullname ) {
00327       ON_DEBUG debug() << "Retrieved tool " << toolname << endmsg;
00328       itool = *it;
00329       break;
00330     }
00331   }
00332 
00333   if ( 0 == itool ) {
00334     // Instances of this tool do not exist, create an instance if desired
00335     // otherwise return failure
00336     if( UNLIKELY(!createIf) ) {
00337       warning() << "Tool " << toolname
00338                 << " not found and creation not requested" << endmsg;
00339       return sc;
00340     }
00341     else {
00342       sc = create( tooltype, toolname, parent, itool );
00343       if ( sc.isFailure() ) { return sc; }
00344     }
00345   }
00346 
00347   // Get the right interface of it
00348   sc = itool->queryInterface( iid, (void**)&tool);
00349   if( UNLIKELY(sc.isFailure()) ) {
00350     error() << "Tool " << toolname
00351         << " either does not implement the correct interface, or its version is incompatible"
00352         << endmsg;
00353     return sc;
00354   }
00358   if (!m_observers.empty()) {
00359      std::for_each( m_observers.begin(),
00360                     m_observers.end(),
00361                     bl::bind(&IToolSvc::Observer::onRetrieve,
00362                              bl::_1,
00363                              itool));
00364   }
00365 
00366   return sc;
00367 }
00368 //------------------------------------------------------------------------------
00369 std::vector<std::string> ToolSvc::getInstances( const std::string& toolType )
00370 //------------------------------------------------------------------------------
00371 {
00372 
00373   std::vector<std::string> tools;
00374 
00375   ListTools::const_iterator it;
00376   for (it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it) {
00377     if ((*it)->type() == toolType) {
00378       tools.push_back( (*it)->name() );
00379     }
00380   }
00381 
00382   return tools;
00383 
00384 }
00385 //------------------------------------------------------------------------------
00386 StatusCode ToolSvc::releaseTool( IAlgTool* tool )
00387   //------------------------------------------------------------------------------
00388 {
00389   StatusCode sc(StatusCode::SUCCESS);
00390   // test if tool is in known list (protect trying to access a previously deleted tool)
00391   if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(),
00392                                               m_instancesTools.rend(),
00393                                               tool ) ) {
00394     unsigned long count = refCountTool(tool);
00395     if ( count == 1 ) {
00396       MsgStream log( msgSvc(), name() );
00397       // finalize the tool
00398 
00399       if ( Gaudi::StateMachine::OFFLINE == m_targetState ) {
00400         // We are being called during ToolSvc::finalize()
00401         // message format matches the one in ToolSvc::finalize()
00402         log << MSG::DEBUG << "  Performing finalization of " << tool->name()
00403             << " (refCount " << count << ")" << endmsg;
00404         // message format matches the one in ToolSvc::finalize()
00405         log << MSG::DEBUG << "  Performing     deletion of " << tool->name() << endmsg;
00406       } else {
00407         log << MSG::DEBUG << "Performing finalization and deletion of " << tool->name() << endmsg;
00408       }
00409       sc = finalizeTool(tool);
00410       // remove from known tools...
00411       m_instancesTools.remove(tool);
00412     }
00413     tool->release();
00414   }
00415 
00416   return sc;
00417 }
00418 
00419 //------------------------------------------------------------------------------
00420 StatusCode ToolSvc::create(const std::string& tooltype,
00421                            const IInterface* parent,
00422                            IAlgTool*& tool)
00423   //------------------------------------------------------------------------------
00424 {
00425   const std::string & toolname = tooltype;
00426   return create( tooltype, toolname, parent, tool);
00427 }
00428 
00429 namespace {
00432 class ToolCreateGuard {
00433 public:
00434   ToolCreateGuard(ToolSvc::ListTools &listTools):
00435     m_list(listTools),
00436     m_tool(0)
00437   {}
00439   void set(IAlgTool* tool) {
00440     if (m_tool) { // remove previous content
00441       m_list.remove(m_tool);
00442       delete m_tool;
00443     }
00444     if (tool) { // set new content
00445       m_tool = tool;
00446       m_list.push_back(m_tool);
00447     }
00448   }
00449   ToolCreateGuard& operator=(IAlgTool* tool) {
00450     set(tool);
00451     return *this;
00452   }
00454   IAlgTool* get() {
00455     return m_tool;
00456   }
00457   IAlgTool* operator->() const {
00458     assert(m_tool != 0);
00459     return m_tool;
00460   }
00462   IAlgTool* release() {
00463     IAlgTool* tool = m_tool;
00464     m_tool = 0;
00465     return tool;
00466   }
00468   ~ToolCreateGuard(){
00469     set(0);
00470   }
00471 private:
00473   ToolSvc::ListTools& m_list;
00475   IAlgTool* m_tool;
00476 };
00477 }
00478 //------------------------------------------------------------------------------
00479 StatusCode ToolSvc::create(const std::string& tooltype,
00480                            const std::string& toolname,
00481                            const IInterface* parent,
00482                            IAlgTool*& tool)
00483   //------------------------------------------------------------------------------
00484 {
00485   // protect against empty type
00486   if ( UNLIKELY(tooltype.empty()) ) {
00487     error() << "create(): No Tool Type given" << endmsg;
00488     return StatusCode::FAILURE;
00489   }
00490 
00491   // If parent has not been specified, assume it is the ToolSvc
00492   if ( 0 == parent ) parent = this;
00493 
00494   tool = 0;
00495   // Automatically deletes the tool if not explicitly kept (i.e. on success).
00496   // The tool is removed from the list of known tools too.
00497   ToolCreateGuard toolguard(m_instancesTools);
00498 
00499   // Check if the tool already exist : this should never happen
00500   const std::string fullname = nameTool(toolname, parent);
00501   if( UNLIKELY(existsTool(fullname)) ) {
00502     error() << "Tool " << fullname << " already exists" << endmsg;
00503     return StatusCode::FAILURE;
00504   }
00505   // instantiate the tool using the factory
00506   try {
00507     toolguard = PluginService::Create<IAlgTool*>(tooltype, tooltype, fullname, parent);
00508     if ( UNLIKELY(! toolguard.get()) ){
00509        error() << "Cannot create tool " << tooltype << " (No factory found)" << endmsg;
00510        return StatusCode::FAILURE;
00511     }
00512   }
00513   catch ( const GaudiException& Exception )  {
00514     // (1) perform the printout of message
00515     fatal() << "Exception with tag=" << Exception.tag()
00516             << " is caught whilst instantiating tool '" << tooltype << "'" << endmsg;
00517     // (2) print  the exception itself
00518     // (NB!  - GaudiException is a linked list of all "previous exceptions")
00519     fatal() << Exception  << endmsg;
00520     return StatusCode::FAILURE;
00521   }
00522   catch( const std::exception& Exception ) {
00523     // (1) perform the printout of message
00524     fatal() << "Standard std::exception is caught whilst instantiating tool '"
00525             << tooltype << "'" << endmsg;
00526     // (2) print  the exception itself
00527     // (NB!  - GaudiException is a linked list of all "previous exceptions")
00528     fatal() << Exception.what()  << endmsg;
00529     return StatusCode::FAILURE;
00530   }
00531   catch(...) {
00532     // (1) perform the printout
00533     fatal() << "UNKNOWN Exception is caught whilst instantiating tool '"
00534             << tooltype << "'" << endmsg;
00535     return StatusCode::FAILURE;
00536   }
00537   ON_VERBOSE verbose() << "Created tool " << tooltype << "/" << fullname << endmsg;
00538 
00539   // Since only AlgTool has the setProperties() method it is necessary to cast
00540   // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
00541   // service
00542   AlgTool* mytool = dynamic_cast<AlgTool*> (toolguard.get());
00543   if ( mytool != 0 ) {
00544     StatusCode sc = mytool->setProperties();
00545     if ( UNLIKELY(sc.isFailure()) ) {
00546       error() << "Error setting properties for tool '"
00547               << fullname << "'" << endmsg;
00548       return sc;
00549     }
00550   }
00551 
00552   // Initialize the Tool
00553   StatusCode sc (StatusCode::FAILURE,true);
00554   try {
00555     sc = toolguard->sysInitialize();
00556   }
00557   // Catch any exceptions
00558   catch ( const GaudiException & Exception )
00559     {
00560       error()
00561           << "GaudiException with tag=" << Exception.tag()
00562           << " caught whilst initializing tool '" << fullname << "'" << endmsg
00563           << Exception << endmsg;
00564       return StatusCode::FAILURE;
00565     }
00566   catch( const std::exception & Exception )
00567     {
00568       error()
00569           << "Standard std::exception caught whilst initializing tool '"
00570           << fullname << "'" << endmsg << Exception.what() << endmsg;
00571       return StatusCode::FAILURE;
00572     }
00573   catch (...)
00574     {
00575       error()
00576           << "UNKNOWN Exception caught whilst initializing tool '"
00577           << fullname << "'" << endmsg;
00578       return StatusCode::FAILURE;
00579     }
00580 
00581   // Status of tool initialization
00582   if ( UNLIKELY(sc.isFailure()) ) {
00583     error() << "Error initializing tool '" << fullname << "'" << endmsg;
00584     return sc;
00585   }
00586 
00587   // Start the tool if we are running.
00588   if (m_state == Gaudi::StateMachine::RUNNING) {
00589     sc = toolguard->sysStart();
00590 
00591     if (UNLIKELY(sc.isFailure())) {
00592       error() << "Error starting tool '" << fullname << "'" << endmsg;
00593       return sc;
00594     }
00595   }
00596 
00597 
00598   // The tool has been successfully created and initialized,
00599   // so we the guard can be released
00600   tool = toolguard.release();
00601 
00605   if (!m_observers.empty()) {
00606       std::for_each( m_observers.begin(),
00607                      m_observers.end(),
00608                      bl::bind(&IToolSvc::Observer::onCreate,
00609                               bl::_1,
00610                               tool));
00611   }
00612   // TODO: replace by generic callback
00613   // Register the tool with the HistorySvc
00614   if (m_pHistorySvc != 0 ||
00615       service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
00616     m_pHistorySvc->registerAlgTool(*tool).ignore();
00617   }
00618 
00619   return StatusCode::SUCCESS;
00620 
00621 }
00622 
00623 //------------------------------------------------------------------------------
00624 std::string ToolSvc::nameTool( const std::string& toolname,
00625                                const IInterface* parent )
00626   //------------------------------------------------------------------------------
00627 {
00628 
00629   std::string fullname = "";
00630   if ( parent == 0 ) { return this->name() + "." + toolname; }    // RETURN
00631 
00632 
00633   IInterface* cparent = const_cast<IInterface*>( parent ) ;
00634   // check that parent has a name!
00635   INamedInterface* _p = 0 ;
00636   StatusCode sc = cparent->queryInterface( INamedInterface::interfaceID() , pp_cast<void>(&_p) ) ;
00637   if ( sc.isSuccess() )
00638   {
00639     fullname = _p->name() + "." + toolname ;
00640     _p->release() ;
00641     return fullname ;                                          // RETURN
00642   }
00643 
00644   MsgStream log ( msgSvc(), name() );
00645   log << MSG::ERROR
00646       << "Private Tools only allowed for components implementing INamedInterface"
00647       << endmsg;
00648   //
00649   return "." + toolname ;
00650 }
00651 
00652 //------------------------------------------------------------------------------
00653 bool ToolSvc::existsTool( const std::string& fullname) const
00654   //------------------------------------------------------------------------------
00655 {
00656   for ( ListTools::const_iterator it = m_instancesTools.begin();
00657         it != m_instancesTools.end(); ++it ) {
00658     if ( (*it)->name() == fullname ) { return true; }
00659   }
00660   return false;
00661 }
00662 
00663 //------------------------------------------------------------------------------
00664 StatusCode ToolSvc::finalizeTool( IAlgTool* itool ) const
00665   //------------------------------------------------------------------------------
00666 {
00667 
00668   // Cache tool name in case of errors
00669   const std::string toolName = itool->name();
00670   StatusCode sc;
00671 
00672   // Finalise the tool inside a try block
00673   try {
00674     sc = itool->sysFinalize();
00675   }
00676   // Catch any exceptions
00677   catch ( const GaudiException & Exception )
00678   {
00679     error()
00680         << "GaudiException with tag=" << Exception.tag()
00681         << " caught whilst finalizing tool '" << toolName << "'" << endmsg
00682         << Exception << endmsg;
00683     sc = StatusCode::FAILURE;
00684   }
00685   catch( const std::exception & Exception )
00686   {
00687     error()
00688         << "Standard std::exception caught whilst finalizing tool '"
00689         << toolName << "'" << endmsg << Exception.what() << endmsg;
00690     sc = StatusCode::FAILURE;
00691   }
00692   catch (...)
00693   {
00694     error()
00695         << "UNKNOWN Exception caught whilst finalizing tool '"
00696         << toolName << "'" << endmsg;
00697     sc = StatusCode::FAILURE;
00698   }
00699 
00700   return sc;
00701 
00702 }
00703 
00704 //------------------------------------------------------------------------------
00705 unsigned long ToolSvc::totalToolRefCount( const ToolSvc::ListTools& toolList ) const
00706 //------------------------------------------------------------------------------
00707 {
00708   unsigned long count = 0;
00709   for ( ListTools::const_iterator iTool = toolList.begin();
00710         iTool != toolList.end(); ++iTool ) {
00711     count += refCountTool( *iTool );
00712   }
00713   return count;
00714 }
00715 
00716 //------------------------------------------------------------------------------
00717 unsigned long ToolSvc::totalToolRefCount() const
00718 //------------------------------------------------------------------------------
00719 {
00720   return totalToolRefCount( m_instancesTools );
00721 }
00722 //------------------------------------------------------------------------------
00723 unsigned long ToolSvc::minimumToolRefCount() const
00724 //------------------------------------------------------------------------------
00725 {
00726   unsigned long count = 0;
00727   if ( m_instancesTools.size() > 0 ) {
00728     ListTools::const_iterator iTool = m_instancesTools.begin();
00729     // start with first
00730     count = refCountTool( *iTool );
00731     // then compare the others
00732     for( ++iTool; iTool != m_instancesTools.end(); ++iTool ) {
00733       count = std::min( count, refCountTool( *iTool ) );
00734     }
00735   }
00736   return count;
00737 }
00738 
00739 void ToolSvc::registerObserver(IToolSvc::Observer* obs) {
00740   if ( 0 == obs )
00741     throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
00742   m_observers.push_back(obs);
00743 }
00744 
00745 void ToolSvc::unRegisterObserver(IToolSvc::Observer* obs) {
00746   std::vector<IToolSvc::Observer*>::iterator i =
00747     find(m_observers.begin(),m_observers.end(),obs);
00748   if (i!=m_observers.end()) m_observers.erase(i);
00749 }
00750 
00751 //------------------------------------------------------------------------------
00752 StatusCode
00753 ToolSvc::start()
00754 //------------------------------------------------------------------------------
00755 {
00756 
00757   ON_DEBUG debug() << "START transition for AlgTools" << endmsg;
00758 
00759   bool fail(false);
00760   for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00761         iTool != m_instancesTools.end(); ++iTool ) {
00762     ON_VERBOSE verbose() << (*iTool)->name() << "::start()" << endmsg;
00763 
00764     if (UNLIKELY(!(*iTool)->sysStart().isSuccess())) {
00765       fail = true;
00766       error() << (*iTool)->name() << " failed to start()" << endmsg;
00767     }
00768 
00769   }
00770 
00771   if (UNLIKELY(fail)) {
00772     error() << "One or more AlgTools failed to start()" << endmsg;
00773     return StatusCode::FAILURE;
00774   } else {
00775     return StatusCode::SUCCESS;
00776   }
00777 
00778 }
00779 
00780 //------------------------------------------------------------------------------
00781 StatusCode
00782 ToolSvc::stop()
00783 //------------------------------------------------------------------------------
00784 {
00785 
00786   ON_DEBUG debug() << "STOP transition for AlgTools" << endmsg;
00787 
00788   bool fail(false);
00789   for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00790         iTool != m_instancesTools.end(); ++iTool ) {
00791     ON_VERBOSE verbose() << (*iTool)->name() << "::stop()" << endmsg;
00792 
00793     if (UNLIKELY(!(*iTool)->sysStop().isSuccess())) {
00794       fail = true;
00795       error() << (*iTool)->name() << " failed to stop()" << endmsg;
00796     }
00797 
00798   }
00799 
00800   if (UNLIKELY(fail)) {
00801     error() << "One or more AlgTools failed to stop()" << endmsg;
00802     return StatusCode::FAILURE;
00803   } else {
00804     return StatusCode::SUCCESS;
00805   }
00806 
00807 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines

Generated at Fri Sep 2 2011 16:25:02 for Gaudi Framework, version v22r4 by Doxygen version 1.7.2 written by Dimitri van Heesch, © 1997-2004