| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# ToolSvc.cpp

Go to the documentation of this file.

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

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines