Gaudi Framework, version v21r7

Home   Generated: 22 Jan 2010

ToolSvc.cpp

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

Generated at Fri Jan 22 20:28:11 2010 for Gaudi Framework, version v21r7 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004