Gaudi Framework, version v20r2

Generated: 18 Jul 2008

ToolSvc Class Reference

#include <ToolSvc.h>

Inheritance diagram for ToolSvc:

Inheritance graph
[legend]
Collaboration diagram for ToolSvc:

Collaboration graph
[legend]
List of all members.

Detailed Description

This service manages tools.

Tools can be common, in which case a single instance can be shared by different algorithms, or private in which case it is necessary to specify the parent when requesting it. The parent of a tool can be an algortihm or a Service The environment of a tool is set by using that of the parent. A common tool is considered to belong to the ToolSvc itself.

Author:
G. Corti, P. Mato

Definition at line 23 of file ToolSvc.h.

Public Types

typedef std::list< IAlgTool * > ListTools

Public Member Functions

virtual StatusCode initialize ()
 Initialize the service.
virtual StatusCode finalize ()
 Finalize the service.
virtual StatusCode queryInterface (const InterfaceID &riid, void **ppvInterface)
 Query the interfaces.
virtual StatusCode retrieve (const std::string &type, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent, bool createIf)
 Retrieve tool, create it by default as common tool if it does not already exist.
virtual StatusCode retrieve (const std::string &tooltype, const std::string &toolname, const InterfaceID &iid, IAlgTool *&tool, const IInterface *parent, bool createIf)
 Retrieve tool, create it by default as common tool if it does not already exist.
virtual std::vector< std::stringgetInstances (const std::string &toolType)
 Get names of all tool instances of a given type.
virtual StatusCode releaseTool (IAlgTool *tool)
 Release tool.
StatusCode create (const std::string &type, const IInterface *parent, IAlgTool *&tool)
 Create Tool standard way with automatically assigned name.
StatusCode create (const std::string &type, const std::string &name, const IInterface *parent, IAlgTool *&tool)
 Create Tool standard way with specified name.
bool existsTool (const std::string &toolname) const
 Check if the tool instance exists.
std::string nameTool (const std::string &nameByUser, const IInterface *parent)
 Get Tool full name by combining nameByUser and "parent" part.
unsigned long refCountTool (IAlgTool *tool) const
 Get current refcount for tool.
 ToolSvc (const std::string &name, ISvcLocator *svc)
 Standard Constructor.
virtual ~ToolSvc ()
 Destructor.
virtual void registerObserver (IToolSvc::Observer *obs)
virtual void unRegisterObserver (IToolSvc::Observer *obs)

Private Member Functions

unsigned long totalToolRefCount () const
 The total number of refCounts on all tools in the instancesTools list.
unsigned long totalToolRefCount (const ListTools &) const
 The total number of refCounts on all tools in the list.
unsigned long minimumToolRefCount () const
 The minimum number of refCounts of all tools.
StatusCode finalizeTool (IAlgTool *itool) const
 Finalise the given tool, with exception handling.

Private Attributes

ListTools m_instancesTools
 Common Tools.
IHistorySvcm_pHistorySvc
 Pointer to HistorySvc.
std::vector< IToolSvc::Observer * > m_observers


Member Typedef Documentation

typedef std::list<IAlgTool*> ToolSvc::ListTools

Definition at line 28 of file ToolSvc.h.


Constructor & Destructor Documentation

ToolSvc::ToolSvc ( const std::string name,
ISvcLocator svc 
)

Standard Constructor.

Parameters:
name String with service name
svc Pointer to service locator interface

Definition at line 29 of file ToolSvc.cpp.

00031   : Service(name, svc),
00032     m_pHistorySvc(0)
00033  { }

ToolSvc::~ToolSvc (  )  [virtual]

Destructor.

Definition at line 36 of file ToolSvc.cpp.

00038 { 
00039 
00040 }


Member Function Documentation

StatusCode ToolSvc::initialize (  )  [virtual]

Initialize the service.

Reimplemented from Service.

Definition at line 43 of file ToolSvc.cpp.

References endreq(), MSG::ERROR, StatusCode::FAILURE, Service::initialize(), StatusCode::isFailure(), Service::msgSvc(), Service::name(), and Service::setProperties().

00045 {
00046 
00047   // initialize the Service Base class
00048   StatusCode status = Service::initialize();
00049   if ( status.isFailure() )
00050   {
00051     MsgStream log( msgSvc(), name() );
00052     log << MSG::ERROR << "Unable to initialize the Service" << endreq;
00053     return status;
00054   }
00055 
00056   // set my own (ToolSvc) properties via the jobOptionService
00057   if (setProperties().isFailure()) {
00058     MsgStream log( msgSvc(), name() );
00059     log << MSG::ERROR << "Unable to set base properties" << endreq;
00060     return StatusCode::FAILURE;
00061   }
00062 
00063   return status;
00064 }

StatusCode ToolSvc::finalize (  )  [virtual]

Finalize the service.

Algorithm: 2 passes. First pass:

Inner loop: full loop over all left-over tools + finalize tools with the minimum number of refCounts in the list. + Remove finalized tools from list of tools, and add them to the list of finalized tools, to be deleted at the end. This way, any non-finalized tools who still reference already finalized tools in their finalize() will still find a live tool. Outer loop: keep on going until nothing changes in the list of tools. Checking for: + number of left-over tools + total number of refcounts + minimum number of refcounts

Reimplemented from Service.

Definition at line 67 of file ToolSvc.cpp.

References std::list< _Tp, _Alloc >::back(), std::list< _Tp, _Alloc >::begin(), count(), MSG::DEBUG, std::list< _Tp, _Alloc >::empty(), std::list< _Tp, _Alloc >::end(), endreq(), MSG::ERROR, StatusCode::FAILURE, Service::finalize(), finalizeTool(), std::list< _Tp, _Alloc >::front(), MSG::INFO, m_instancesTools, m_pHistorySvc, minimumToolRefCount(), Service::msgSvc(), Service::name(), std::list< _Tp, _Alloc >::pop_back(), std::list< _Tp, _Alloc >::pop_front(), std::list< _Tp, _Alloc >::push_back(), std::list< _Tp, _Alloc >::push_front(), refCountTool(), IInterface::release(), std::list< _Tp, _Alloc >::size(), StatusCode::SUCCESS, totalToolRefCount(), and MSG::VERBOSE.

00069 {
00070   // Finalize and delete all left-over tools. Normally all tools created with 
00071   // ToolSvc are left over, since ToolSvc holds a refCount (via AlgTool ctor).
00072   // Several cases need to be covered:
00073   // 1) Simple dependencies: no circular dependencies between tools,
00074   //    and tools not using other tools
00075   // 2) Tools-using-tools (but no circular dependencies)
00076   //   a) release() is called in the tool::finalize() (e.g. via GaudiAlgorithm)
00077   //   b) release() is called in the tool destructor  (e.g. via ToolHandle)
00078   // 3) Circular dependencies between tools
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   // 4) In addition to each of the above cases, refCounting of a particular tool 
00082   //    might not have been done correctly in the code. Typically release() 
00083   //    is not called, so we are left with a too high refCount.
00084   //    What to do with those, and how to avoid a crash while handling them...
00085   
00094   MsgStream log( msgSvc(), name() );
00095   ListTools finalizedTools; // list of tools that have been finalized
00096   log << MSG::INFO  << "Removing all tools created by ToolSvc" << endreq;
00097 
00098   // Print out list of tools
00099   log << MSG::DEBUG << "  Tool List : ";
00100   for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00101         iTool != m_instancesTools.end(); ++iTool ) {
00102     log << (*iTool)->name() << ":" << refCountTool( *iTool ) << " ";
00103   }
00104   log << endreq;
00105 
00106   //
00107   // first pass: Finalize all tools (but don't delete them)
00108   //
00121   bool fail(false);
00122   size_t toolCount = m_instancesTools.size();
00123   unsigned long startRefCount = 0;
00124   unsigned long endRefCount = totalToolRefCount();
00125   unsigned long startMinRefCount = 0;
00126   unsigned long endMinRefCount = minimumToolRefCount();
00127   while ( toolCount > 0 && 
00128           endRefCount > 0 && 
00129           (endRefCount != startRefCount || endMinRefCount != startMinRefCount) ) {
00130     if ( endMinRefCount != startMinRefCount ) {
00131       log << MSG::DEBUG << toolCount << " tools left to finalize. Summed refCounts: " 
00132           << endRefCount << endreq;
00133       log << MSG::DEBUG << "Will finalize tools with refCount <= " 
00134           << endMinRefCount << endreq;
00135     }
00136     startMinRefCount = endMinRefCount;
00137     startRefCount = endRefCount;
00138     unsigned long maxLoop = toolCount + 1;
00139     while ( --maxLoop > 0 &&  m_instancesTools.size() > 0 ) {
00140       IAlgTool* pTool = m_instancesTools.back();
00141       // removing tool from list makes ToolSvc::releaseTool( IAlgTool* ) a noop
00142       m_instancesTools.pop_back();
00143       unsigned long count = refCountTool( pTool );
00144       // cache tool name
00145       std::string toolName = pTool->name();
00146       if ( count <= startMinRefCount ) {
00147         log << MSG::DEBUG << "  Performing finalization of " << toolName 
00148             << " (refCount " << count << ")" << endreq;
00149         // finalize of one tool may trigger a release of another tool
00150         //      pTool->sysFinalize().ignore();
00151         if (!finalizeTool(pTool).isSuccess()) fail = true;
00152         // postpone deletion
00153         finalizedTools.push_back(pTool);
00154       } else {
00155         // Place back in list to try again later
00156         // ToolSvc::releaseTool( IAlgTool* ) remains active for this tool
00157         log << MSG::DEBUG << "  Delaying   finalization of " << toolName
00158             << " (refCount " << count << ")" << endreq;
00159         m_instancesTools.push_front(pTool);
00160       }
00161     } // end of inner loop
00162     toolCount = m_instancesTools.size();
00163     endRefCount = totalToolRefCount();
00164     endMinRefCount = minimumToolRefCount();
00165   }; // end of outer loop
00166 
00167   //
00168   // Second pass: Delete all finalized tools
00169   //
00170   // Delete in the order of increasing number of refCounts. 
00171   // Loop over tools in the same order as the order in which they were finalized.
00172   // All tools in the list of finalized tools are no longer in the instancesTools list.
00173   // If a tool destructor calls releaseTool() on another tool, this will have no
00174   // effect on the 'other tool' if this 'other tool' is in the list of finalized tools.
00175   // If this 'other tool' is still in the instancesTools list, it may trigger finalization
00176   // (in releaseTool()), deletion and removal from the instancesTools list.
00177   // Therefore, the check on non-finalised tools should happen *after* the deletion
00178   // of the finalized tools.
00179   log << MSG::DEBUG << "Deleting " << finalizedTools.size() << " finalized tools" << endreq;
00180   unsigned long maxLoop = totalToolRefCount( finalizedTools ) + 1;
00181   while ( --maxLoop > 0 && finalizedTools.size() > 0 ) {
00182     IAlgTool* pTool = finalizedTools.front();
00183     finalizedTools.pop_front();
00184     unsigned long count = refCountTool( pTool );
00185     if ( count == 1 ) {
00186       log << MSG::DEBUG << "  Performing deletion of " << pTool->name() << endreq;
00187     } else {
00188       log << MSG::VERBOSE << "  Delaying   deletion of " << pTool->name()
00189           << " (refCount " << count << ")" << endreq;
00190       // Put it back at the end of the list if refCount still not zero
00191       finalizedTools.push_back(pTool);
00192     }
00193     // do a forced release
00194     pTool->release();
00195   }
00196 
00197   // Error if by now not all tools are properly finalised
00198   if ( !m_instancesTools.empty() ) {
00199     log << MSG::ERROR << "Unable to finalize and delete the following tools : ";
00200     for ( ListTools::const_iterator iTool = m_instancesTools.begin();
00201           iTool != m_instancesTools.end(); ++iTool ) { 
00202       log << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
00203     }
00204     log << endreq;
00205   }
00206   
00207   // by now, all tools should be deleted and removed.
00208   if ( finalizedTools.size() > 0 ) {
00209     log << MSG::ERROR << "Failed to delete the following " <<  finalizedTools.size() 
00210         << " finalized tools. Bug in ToolSvc::finalize()?: ";
00211     for ( ListTools::const_iterator iTool = finalizedTools.begin();
00212           iTool != finalizedTools.end(); ++iTool ) { 
00213       log << (*iTool)->name() << ": " << refCountTool( *iTool ) << " ";
00214     }
00215     log << endreq;
00216   }
00217   
00218   if ( 0 != m_pHistorySvc ) {
00219     m_pHistorySvc->release();
00220   }
00221   
00222   // Finalize this specific service
00223   if (! Service::finalize().isSuccess() || fail) {
00224     return StatusCode::FAILURE;
00225   } else {
00226     return StatusCode::SUCCESS;
00227   }
00228 
00229 
00230 }

StatusCode ToolSvc::queryInterface ( const InterfaceID riid,
void **  ppvInterface 
) [virtual]

Query the interfaces.

Reimplemented from Service.

Definition at line 233 of file ToolSvc.cpp.

References Service::addRef(), IID_IToolSvc, Service::queryInterface(), and StatusCode::SUCCESS.

00235 {
00236   if ( IID_IToolSvc == riid )    {
00237     *ppvInterface = (IToolSvc*)this;
00238   }
00239   else  {
00240     // Interface is not directly available: try out a base class
00241     return Service::queryInterface(riid, ppvInterface);
00242   }
00243   addRef();
00244   return StatusCode::SUCCESS;
00245 }

StatusCode ToolSvc::retrieve ( const std::string type,
const InterfaceID iid,
IAlgTool *&  tool,
const IInterface parent,
bool  createIf 
) [virtual]

Retrieve tool, create it by default as common tool if it does not already exist.

Implements IToolSvc.

Definition at line 258 of file ToolSvc.cpp.

References std::basic_string< _CharT, _Traits, _Alloc >::empty(), endreq(), MSG::ERROR, StatusCode::FAILURE, std::basic_string< _CharT, _Traits, _Alloc >::find(), Service::msgSvc(), Service::name(), std::basic_string< _CharT, _Traits, _Alloc >::npos, and s_PUBLIC.

Referenced by retrieve().

00264 {
00265 
00266   // protect against empty type
00267   if ( tooltype.empty() ) {
00268     MsgStream log( msgSvc(), name() );
00269     log << MSG::ERROR << "retrieve(): No Tool Type/Name given" << endreq;
00270     return StatusCode::FAILURE;
00271   }
00272   
00273   {
00274     // check for tools, which by name is required to be public:
00275     const std::string::size_type pos = tooltype.find ( s_PUBLIC ) ;
00276     if ( std::string::npos != pos )
00277     {
00278       // set parent for PUBLIC tool
00279       parent = this ;
00280       return retrieve ( std::string( tooltype , 0 , pos ) ,
00281                         iid , tool , parent , createIf ) ;
00282     }
00283   }
00284 
00285   const std::string::size_type pos = tooltype.find('/');
00286   if( std::string::npos == pos )
00287   { return retrieve ( tooltype , tooltype , iid , tool , parent , createIf );}
00288   const std::string newtype ( tooltype ,       0 , pos               ) ;
00289   const std::string newname ( tooltype , pos + 1 , std::string::npos ) ;
00290   return retrieve ( newtype , newname , iid , tool , parent , createIf ) ;
00291 }

StatusCode ToolSvc::retrieve ( const std::string tooltype,
const std::string toolname,
const InterfaceID iid,
IAlgTool *&  tool,
const IInterface parent,
bool  createIf 
) [virtual]

Retrieve tool, create it by default as common tool if it does not already exist.

invoke retrieve callbacks...

Implements IToolSvc.

Definition at line 296 of file ToolSvc.cpp.

References std::vector< _Tp, _Alloc >::begin(), std::list< _Tp, _Alloc >::begin(), create(), MSG::DEBUG, std::vector< _Tp, _Alloc >::empty(), std::basic_string< _CharT, _Traits, _Alloc >::empty(), std::vector< _Tp, _Alloc >::end(), std::list< _Tp, _Alloc >::end(), endreq(), MSG::ERROR, StatusCode::FAILURE, std::basic_string< _CharT, _Traits, _Alloc >::find(), std::for_each(), StatusCode::isFailure(), m_instancesTools, m_observers, Service::msgSvc(), Service::name(), nameTool(), std::basic_string< _CharT, _Traits, _Alloc >::npos, IToolSvc::Observer::onRetrieve(), IInterface::queryInterface(), retrieve(), s_PUBLIC, and MSG::WARNING.

00303 {
00304   MsgStream log( msgSvc(), name() );
00305   
00306   // check the applicability of another method:
00307   // ignore the provided name if it is empty or the type contains a name
00308   if( toolname.empty() || (std::string::npos != tooltype.find('/')) )
00309   { return retrieve ( tooltype , iid , tool , parent , createIf ) ; }
00310 
00311   {
00312     // check for tools, which by name is required to be public:
00313     const std::string::size_type pos = toolname.find ( s_PUBLIC ) ;
00314     if ( std::string::npos != pos )
00315     {
00316       // set parent for PUBLIC tool
00317       parent = this ;
00318       return retrieve ( tooltype , std::string( toolname , 0 , pos ) ,
00319                         iid , tool , parent , createIf ) ;
00320     }
00321   }
00322 
00323   IAlgTool* itool = 0;
00324   StatusCode sc(StatusCode::FAILURE);
00325 
00326   tool = 0;
00327 
00328   // If parent is not specified it means it is the ToolSvc itself
00329   if( 0 == parent ) {
00330     parent = this;
00331   }
00332   const std::string fullname = nameTool( toolname, parent );
00333 
00334   // Find tool in list of those already existing, and tell its
00335   // interface that it has been used one more time
00336   ListTools::const_iterator it;
00337   for( it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it ) {
00338     if( (*it)->name() == fullname ) {
00339       log << MSG::DEBUG << "Retrieved tool " << toolname << endreq;
00340       itool = *it;
00341       break;
00342     }
00343   }
00344 
00345   if ( 0 == itool ) {
00346     // Instances of this tool do not exist, create an instance if desired
00347     // otherwise return failure
00348     if( !createIf ) {
00349       log << MSG::WARNING << "Tool " << toolname
00350           << " not found and creation not requested" << endreq;
00351       return sc;
00352     }
00353     else {
00354       sc = create( tooltype, toolname, parent, itool );
00355       if ( sc.isFailure() ) { return sc; }
00356     }
00357   }
00358 
00359   // Get the right interface of it
00360   sc = itool->queryInterface( iid, (void**)&tool);
00361   if( sc.isFailure() ) {
00362     log << MSG::ERROR << "Tool " << toolname
00363         << " either does not implement the correct interface, or its version is incompatible"
00364         << endreq;
00365     return sc;
00366   }
00370   if (!m_observers.empty()) {
00371      std::for_each( m_observers.begin(), 
00372                     m_observers.end(), 
00373                     bl::bind(&IToolSvc::Observer::onRetrieve,
00374                              bl::_1,
00375                              itool));
00376   }
00377 
00378   return sc;
00379 }

std::vector< std::string > ToolSvc::getInstances ( const std::string toolType  )  [virtual]

Get names of all tool instances of a given type.

Implements IToolSvc.

Definition at line 381 of file ToolSvc.cpp.

References std::list< _Tp, _Alloc >::begin(), std::list< _Tp, _Alloc >::end(), m_instancesTools, and std::vector< _Tp, _Alloc >::push_back().

00383 {
00384 
00385   std::vector<std::string> tools;
00386 
00387   ListTools::const_iterator it;
00388   for (it = m_instancesTools.begin(); it != m_instancesTools.end(); ++it) {
00389     if ((*it)->type() == toolType) {
00390       tools.push_back( (*it)->name() );
00391     }
00392   }
00393 
00394   return tools;
00395 
00396 }

StatusCode ToolSvc::releaseTool ( IAlgTool tool  )  [virtual]

Release tool.

Implements IToolSvc.

Definition at line 398 of file ToolSvc.cpp.

References count(), MSG::DEBUG, endreq(), finalizeTool(), std::find(), m_instancesTools, Service::m_targetState, Service::msgSvc(), INamedInterface::name(), Service::name(), Gaudi::StateMachine::OFFLINE, std::list< _Tp, _Alloc >::rbegin(), refCountTool(), IInterface::release(), std::list< _Tp, _Alloc >::remove(), std::list< _Tp, _Alloc >::rend(), and StatusCode::SUCCESS.

00400 {
00401   StatusCode sc(StatusCode::SUCCESS);
00402   // test if tool is in known list (protect trying to access a previously deleted tool)
00403   if ( m_instancesTools.rend() != std::find( m_instancesTools.rbegin(),
00404                                               m_instancesTools.rend(),
00405                                               tool ) ) {
00406     unsigned long count = refCountTool(tool);
00407     if ( count == 1 ) {
00408       MsgStream log( msgSvc(), name() );
00409       // finalize the tool
00410 
00411       if ( Gaudi::StateMachine::OFFLINE == m_targetState ) {
00412         // We are being called during ToolSvc::finalize()
00413         // message format matches the one in ToolSvc::finalize()
00414         log << MSG::DEBUG << "  Performing finalization of " << tool->name()
00415             << " (refCount " << count << ")" << endreq;
00416         // message format matches the one in ToolSvc::finalize()
00417         log << MSG::DEBUG << "  Performing     deletion of " << tool->name() << endreq;
00418       } else {
00419         log << MSG::DEBUG << "Performing finalization and deletion of " << tool->name() << endreq;
00420       }
00421       sc = finalizeTool(tool);
00422       // remove from known tools...
00423       m_instancesTools.remove(tool);
00424     }
00425     tool->release();
00426   }
00427 
00428   return sc;
00429 }

StatusCode ToolSvc::create ( const std::string type,
const IInterface parent,
IAlgTool *&  tool 
)

Create Tool standard way with automatically assigned name.

Definition at line 432 of file ToolSvc.cpp.

Referenced by retrieve().

00436 {
00437   const std::string & toolname = tooltype;
00438   return create( tooltype, toolname, parent, tool);
00439 }

StatusCode ToolSvc::create ( const std::string type,
const std::string name,
const IInterface parent,
IAlgTool *&  tool 
)

Create Tool standard way with specified name.

invoke create callbacks...

Definition at line 442 of file ToolSvc.cpp.

References std::vector< _Tp, _Alloc >::begin(), std::vector< _Tp, _Alloc >::empty(), std::basic_string< _CharT, _Traits, _Alloc >::empty(), std::vector< _Tp, _Alloc >::end(), endreq(), MSG::ERROR, existsTool(), StatusCode::FAILURE, MSG::FATAL, std::for_each(), StatusCode::ignore(), StatusCode::isFailure(), m_instancesTools, m_observers, m_pHistorySvc, Service::msgSvc(), Service::name(), nameTool(), IToolSvc::Observer::onCreate(), std::list< _Tp, _Alloc >::push_back(), IHistorySvc::registerAlgTool(), Service::service(), AlgTool::setProperties(), StatusCode::SUCCESS, IAlgTool::sysInitialize(), GaudiException::tag(), MSG::VERBOSE, and std::exception::what().

00447 {
00448   MsgStream log( msgSvc(), name() );
00449   // protect against empty type
00450   if ( tooltype.empty() ) {
00451     log << MSG::ERROR << "create(): No Tool Type given" << endreq;
00452     return StatusCode::FAILURE;
00453   }
00454 
00455   // If parent has not been specified, assume it is the ToolSvc
00456   if ( 0 == parent ) parent = this;
00457 
00458   tool = 0;
00459 
00460   // Check if the tool already exist : this should never happen
00461   const std::string fullname = nameTool(toolname, parent);
00462   if( existsTool( fullname ) ) {
00463     log << MSG::ERROR << "Tool " << fullname << " already exists" << endreq;
00464     return StatusCode::FAILURE;
00465   }
00466   // instanciate the tool using the factory
00467   try {
00468     tool = PluginService::Create<IAlgTool*>(tooltype, tooltype, fullname, parent);
00469     if (!tool ){
00470        log << MSG::ERROR
00471            << "Cannot create tool " << tooltype << " (No factory found)" << endreq;
00472        return StatusCode::FAILURE;
00473     }
00474   }
00475   catch ( const GaudiException& Exception )  {
00476     // (1) perform the printout of message
00477     MsgStream log ( msgSvc() , name() );
00478     log << MSG::FATAL << "Exception with tag=" << Exception.tag()
00479         << " is caught whilst instantiating tool '" << tooltype << "'" << endreq;
00480     // (2) print  the exception itself
00481     // (NB!  - GaudiException is a linked list of all "previous exceptions")
00482     log << MSG::FATAL << Exception  << endreq;
00483     tool = 0;
00484     return StatusCode::FAILURE;
00485   }
00486   catch( const std::exception& Exception ) {
00487     // (1) perform the printout of message
00488     MsgStream log ( msgSvc() , name() );
00489     log << MSG::FATAL
00490         << "Standard std::exception is caught whilst instantiating tool '"
00491           << tooltype << "'" << endreq;
00492     // (2) print  the exception itself
00493     // (NB!  - GaudiException is a linked list of all "previous exceptions")
00494     log << MSG::FATAL << Exception.what()  << endreq;
00495     tool = 0;
00496     return StatusCode::FAILURE;
00497   }
00498   catch(...) {
00499     // (1) perform the printout
00500     MsgStream log ( msgSvc() , name() );
00501     log << MSG::FATAL << "UNKNOWN Exception is caught whilst instantiating tool '"
00502         << tooltype << "'" << endreq;
00503     tool = 0;
00504     return StatusCode::FAILURE;
00505   }
00506   log << MSG::VERBOSE << "Created tool " << tooltype << "/" << fullname << endreq;
00507   
00508   m_instancesTools.push_back( tool );
00509   
00510   // Since only AlgTool has the setProperties() method it is necessary to cast
00511   // to downcast IAlgTool to AlgTool in order to set the properties via the JobOptions
00512   // service
00513   AlgTool* mytool = dynamic_cast<AlgTool*> (tool);
00514   if ( mytool != 0 ) {
00515     StatusCode sc = mytool->setProperties();
00516     if ( sc.isFailure() ) {
00517       MsgStream log ( msgSvc() , name() );
00518       log << MSG::ERROR << "Error setting properties for tool '"
00519           << fullname << "'" << endreq;
00520       return sc;
00521     }
00522   }
00523   
00524   // Initialize the Tool
00525   StatusCode sc (StatusCode::FAILURE,true);
00526   try { sc = tool->sysInitialize(); }
00527   
00528   // Catch any exceptions
00529   catch ( const GaudiException & Exception )
00530     {
00531       MsgStream msg ( msgSvc(), name() );
00532       msg << MSG::ERROR
00533           << "GaudiException with tag=" << Exception.tag()
00534           << " caught whilst initializing tool '" << fullname << "'" << endreq
00535           << Exception << endreq;
00536       return StatusCode::FAILURE;
00537     }
00538   catch( const std::exception & Exception )
00539     {
00540       MsgStream msg ( msgSvc(), name() );
00541       msg << MSG::ERROR
00542           << "Standard std::exception caught whilst initializing tool '" 
00543           << fullname << "'" << endreq << Exception.what() << endreq;
00544       return StatusCode::FAILURE;
00545     }
00546   catch (...)
00547     {
00548       MsgStream msg ( msgSvc(), name() );
00549       msg << MSG::ERROR
00550           << "UNKNOWN Exception caught whilst initializing tool '" 
00551           << fullname << "'" << endreq;
00552       return StatusCode::FAILURE;
00553     }
00554   
00555   // Status of tool intialization
00556   if ( sc.isFailure() ) {
00557     MsgStream log( msgSvc(), name() );
00558     log << MSG::ERROR << "Error initializing tool '" << fullname << "'" << endreq;
00559     return sc;
00560   }
00561   
00565   if (!m_observers.empty()) {
00566       std::for_each( m_observers.begin(), 
00567                      m_observers.end(), 
00568                      bl::bind(&IToolSvc::Observer::onCreate,
00569                               bl::_1,
00570                               tool));
00571   }
00572   // TODO: replace by generic callback
00573   // Register the tool with the HistorySvc
00574   if (m_pHistorySvc != 0 || 
00575       service("HistorySvc",m_pHistorySvc,false).isSuccess() ) {
00576     m_pHistorySvc->registerAlgTool(*tool).ignore();
00577   }
00578   
00579   return StatusCode::SUCCESS;
00580  
00581 }

bool ToolSvc::existsTool ( const std::string toolname  )  const

Check if the tool instance exists.

Definition at line 613 of file ToolSvc.cpp.

Referenced by create().

00615 {
00616   for ( ListTools::const_iterator it = m_instancesTools.begin(); 
00617         it != m_instancesTools.end(); ++it ) {
00618     if ( (*it)->name() == fullname ) { return true; }
00619   }
00620   return false;
00621 }

std::string ToolSvc::nameTool ( const std::string nameByUser,
const IInterface parent 
)

Get Tool full name by combining nameByUser and "parent" part.

Definition at line 584 of file ToolSvc.cpp.

References endreq(), MSG::ERROR, INamedInterface::interfaceID(), StatusCode::isSuccess(), Service::msgSvc(), Service::name(), and IInterface::queryInterface().

Referenced by create(), and retrieve().

00587 {
00588   
00589   std::string fullname = "";
00590   if ( parent == 0 ) { return this->name() + "." + toolname; }    // RETURN 
00591   
00592   
00593   IInterface* cparent = const_cast<IInterface*>( parent ) ;
00594   // check that parent has a name!
00595   INamedInterface* _p = 0 ;
00596   StatusCode sc = cparent->queryInterface( INamedInterface::interfaceID() , pp_cast<void>(&_p) ) ;
00597   if ( sc.isSuccess() )
00598   { 
00599     fullname = _p->name() + "." + toolname ; 
00600     _p->release() ;
00601     return fullname ;                                          // RETURN 
00602   }
00603 
00604   MsgStream log ( msgSvc(), name() );
00605   log << MSG::ERROR
00606       << "Private Tools only allowed for INamedInterfaces"
00607       << endreq;
00608   //
00609   return "." + toolname ;
00610 }

unsigned long ToolSvc::refCountTool ( IAlgTool tool  )  const [inline]

Get current refcount for tool.

Definition at line 70 of file ToolSvc.h.

References IAlgTool::refCount().

Referenced by finalize(), minimumToolRefCount(), and releaseTool().

00070 { return tool->refCount(); }

void ToolSvc::registerObserver ( IToolSvc::Observer obs  )  [virtual]

Implements IToolSvc.

Definition at line 701 of file ToolSvc.cpp.

References StatusCode::FAILURE, m_observers, and std::vector< _Tp, _Alloc >::push_back().

00701                                                     {
00702   if ( 0 == obs )
00703     throw GaudiException( "Received NULL pointer", this->name() + "::registerObserver", StatusCode::FAILURE );
00704   m_observers.push_back(obs); 
00705 }

void ToolSvc::unRegisterObserver ( IToolSvc::Observer obs  )  [virtual]

Implements IToolSvc.

Definition at line 707 of file ToolSvc.cpp.

References std::vector< _Tp, _Alloc >::begin(), std::vector< _Tp, _Alloc >::end(), std::vector< _Tp, _Alloc >::erase(), find(), and m_observers.

00707                                                       {
00708   std::vector<IToolSvc::Observer*>::iterator i = 
00709     find(m_observers.begin(),m_observers.end(),obs); 
00710   if (i!=m_observers.end()) m_observers.erase(i);
00711 }

unsigned long ToolSvc::totalToolRefCount (  )  const [private]

The total number of refCounts on all tools in the instancesTools list.

Definition at line 679 of file ToolSvc.cpp.

References m_instancesTools.

Referenced by finalize().

00681 {
00682   return totalToolRefCount( m_instancesTools );
00683 }

unsigned long ToolSvc::totalToolRefCount ( const ListTools  )  const [private]

The total number of refCounts on all tools in the list.

Definition at line 667 of file ToolSvc.cpp.

References count().

00669 {
00670   unsigned long count = 0;
00671   for ( ListTools::const_iterator iTool = toolList.begin();
00672         iTool != toolList.end(); ++iTool ) {
00673     count += refCountTool( *iTool );
00674   }
00675   return count;
00676 }

unsigned long ToolSvc::minimumToolRefCount (  )  const [private]

The minimum number of refCounts of all tools.

Definition at line 685 of file ToolSvc.cpp.

References std::list< _Tp, _Alloc >::begin(), count(), std::list< _Tp, _Alloc >::end(), m_instancesTools, std::min(), refCountTool(), and std::list< _Tp, _Alloc >::size().

Referenced by finalize().

00687 {
00688   unsigned long count = 0;
00689   if ( m_instancesTools.size() > 0 ) {
00690     ListTools::const_iterator iTool = m_instancesTools.begin();
00691     // start with first
00692     count = refCountTool( *iTool );
00693     // then compare the others
00694     for( ++iTool; iTool != m_instancesTools.end(); ++iTool ) {
00695       count = std::min( count, refCountTool( *iTool ) );
00696     }
00697   }
00698   return count;
00699 }

StatusCode ToolSvc::finalizeTool ( IAlgTool itool  )  const [private]

Finalise the given tool, with exception handling.

Definition at line 624 of file ToolSvc.cpp.

References endreq(), MSG::ERROR, StatusCode::FAILURE, name, GaudiException::tag(), and std::exception::what().

Referenced by finalize(), and releaseTool().

00626 {
00627 
00628   // Cache tool name in case of errors
00629   const std::string toolName = itool->name();
00630   StatusCode sc;
00631 
00632   // Finalise the tool inside a try block
00633   try { sc = itool->sysFinalize(); }
00634 
00635   // Catch any exceptions
00636   catch ( const GaudiException & Exception )
00637   {
00638     MsgStream msg ( msgSvc(), name() );
00639     msg << MSG::ERROR
00640         << "GaudiException with tag=" << Exception.tag()
00641         << " caught whilst finalizing tool '" << toolName << "'" << endreq
00642         << Exception << endreq;
00643     sc = StatusCode::FAILURE;
00644   }
00645   catch( const std::exception & Exception )
00646   {
00647     MsgStream msg ( msgSvc(), name() );
00648     msg << MSG::ERROR
00649         << "Standard std::exception caught whilst finalizing tool '" 
00650         << toolName << "'" << endreq << Exception.what() << endreq;
00651     sc = StatusCode::FAILURE;
00652   }
00653   catch (...)
00654   {
00655     MsgStream msg ( msgSvc(), name() );
00656     msg << MSG::ERROR
00657         << "UNKNOWN Exception caught whilst finalizing tool '" 
00658         << toolName << "'" << endreq;
00659     sc = StatusCode::FAILURE;
00660   }
00661 
00662   return sc;
00663 
00664 }


Member Data Documentation

ListTools ToolSvc::m_instancesTools [private]

Common Tools.

Definition at line 102 of file ToolSvc.h.

Referenced by create(), finalize(), getInstances(), minimumToolRefCount(), releaseTool(), retrieve(), and totalToolRefCount().

IHistorySvc* ToolSvc::m_pHistorySvc [private]

Pointer to HistorySvc.

Definition at line 105 of file ToolSvc.h.

Referenced by create(), and finalize().

std::vector<IToolSvc::Observer*> ToolSvc::m_observers [private]

Definition at line 107 of file ToolSvc.h.

Referenced by create(), registerObserver(), retrieve(), and unRegisterObserver().


The documentation for this class was generated from the following files:
Generated at Fri Jul 18 12:09:35 2008 for Gaudi Framework, version v20r2 by Doxygen version 1.5.1 written by Dimitri van Heesch, © 1997-2004