The Gaudi Framework  v33r1 (b1225454)
AlgTool.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // Include files
12 #include "GaudiKernel/AlgTool.h"
17 
18 #include "GaudiKernel/Auditor.h"
21 #include "GaudiKernel/Guards.h"
22 #include "GaudiKernel/Service.h"
24 #include "GaudiKernel/System.h"
25 #include "GaudiKernel/ToolHandle.h"
26 #include <Gaudi/Algorithm.h>
27 
28 //------------------------------------------------------------------------------
29 namespace {
30  template <typename FUN>
31  StatusCode attempt( AlgTool& tool, const char* label, FUN&& fun ) {
32  try {
33  return fun();
34  } catch ( const GaudiException& Exception ) {
35  MsgStream log( tool.msgSvc(), tool.name() + "." + label );
36  log << MSG::FATAL << " Exception with tag=" << Exception.tag() << " is caught" << endmsg;
37  log << MSG::ERROR << Exception << endmsg;
38  } catch ( const std::exception& Exception ) {
39  MsgStream log( tool.msgSvc(), tool.name() + "." + label );
40  log << MSG::FATAL << " Standard std::exception is caught" << endmsg;
41  log << MSG::ERROR << Exception.what() << endmsg;
42  } catch ( ... ) {
43  MsgStream log( tool.msgSvc(), tool.name() + "." + label );
44  log << MSG::FATAL << "UNKNOWN Exception is caught" << endmsg;
45  }
46  return StatusCode::FAILURE;
47  }
48 } // namespace
49 
50 //------------------------------------------------------------------------------
51 StatusCode AlgTool::queryInterface( const InterfaceID& riid, void** ppvi )
52 //------------------------------------------------------------------------------
53 {
54  if ( !ppvi ) { return StatusCode::FAILURE; } // RETURN
55  StatusCode sc = base_class::queryInterface( riid, ppvi );
56  if ( sc.isSuccess() ) return sc;
58  [&]( const std::pair<InterfaceID, void*>& item ) { return item.first.versionMatch( riid ); } );
59  if ( i == std::end( m_interfaceList ) ) {
60  *ppvi = nullptr;
61  return Status::NO_INTERFACE; // RETURN
62  }
63  *ppvi = i->second;
64  addRef();
65  return StatusCode::SUCCESS; // RETURN
66 }
67 //------------------------------------------------------------------------------
68 const std::string& AlgTool::name() const
69 //------------------------------------------------------------------------------
70 {
71  return m_name;
72 }
73 
74 //------------------------------------------------------------------------------
75 const std::string& AlgTool::type() const
76 //------------------------------------------------------------------------------
77 {
78  return m_type;
79 }
80 
81 //------------------------------------------------------------------------------
83 //------------------------------------------------------------------------------
84 {
85  return m_parent;
86 }
87 
88 //------------------------------------------------------------------------------
90 //------------------------------------------------------------------------------
91 {
92  return m_svcLocator;
93 }
94 
95 // ============================================================================
96 // accessor to event service service
97 // ============================================================================
99  if ( !m_evtSvc ) {
100  m_evtSvc = service( "EventDataSvc", true );
101  if ( !m_evtSvc ) { throw GaudiException( "Service [EventDataSvc] not found", name(), StatusCode::FAILURE ); }
102  }
103  return m_evtSvc.get();
104 }
105 //------------------------------------------------------------------------------
107 //------------------------------------------------------------------------------
108 {
109  if ( !m_ptoolSvc ) {
110  m_ptoolSvc = service( "ToolSvc", true );
111  if ( !m_ptoolSvc ) { throw GaudiException( "Service [ToolSvc] not found", name(), StatusCode::FAILURE ); }
112  }
113  return m_ptoolSvc.get();
114 }
115 
116 //------------------------------------------------------------------------------
118 //------------------------------------------------------------------------------
119 {
120  if ( !m_svcLocator ) return StatusCode::FAILURE;
121  auto jos = m_svcLocator->service<IJobOptionsSvc>( "JobOptionsSvc" );
122  if ( !jos ) return StatusCode::FAILURE;
123 
124  return jos->setMyProperties( name(), this );
125 }
126 
127 //------------------------------------------------------------------------------
129  //------------------------------------------------------------------------------
130  : m_type( std::move( type ) ), m_name( std::move( name ) ), m_parent( parent ) {
131  addRef(); // Initial count set to 1
132 
133  IInterface* _p = const_cast<IInterface*>( parent );
134 
135  if ( Gaudi::Algorithm* _alg = dynamic_cast<Gaudi::Algorithm*>( _p ) ) {
136  m_svcLocator = _alg->serviceLocator();
137  } else if ( Service* _svc = dynamic_cast<Service*>( _p ) ) {
138  m_svcLocator = _svc->serviceLocator();
139  } else if ( AlgTool* _too = dynamic_cast<AlgTool*>( _p ) ) {
140  m_svcLocator = _too->serviceLocator();
141  } else if ( Auditor* _aud = dynamic_cast<Auditor*>( _p ) ) {
142  m_svcLocator = _aud->serviceLocator();
143  } else {
144  throw GaudiException( "Failure to create tool '" + m_type + "/" + m_name + "': illegal parent type '" +
145  System::typeinfoName( typeid( *_p ) ) + "'",
146  "AlgTool", StatusCode::FAILURE );
147  }
148 
149  // inherit output level from parent
150  // get the "OutputLevel" property from parent
151  if ( SmartIF<IProperty> pprop( _p ); pprop && pprop->hasProperty( "OutputLevel" ) ) {
152  m_outputLevel.assign( pprop->getProperty( "OutputLevel" ) );
153  }
154 
155  // Auditor monitoring properties
156  // Initialize the default value from ApplicationMgr AuditAlgorithms
157  Gaudi::Property<bool> audit( false );
158  // note that here we need that the service locator is already defined
159  if ( auto appMgr = serviceLocator()->service<IProperty>( "ApplicationMgr" );
160  appMgr && appMgr->hasProperty( "AuditTools" ) ) {
161  audit.assign( appMgr->getProperty( "AuditTools" ) );
162  }
163  m_auditInit = audit;
164  m_auditorInitialize = audit;
165  m_auditorStart = audit;
166  m_auditorStop = audit;
167  m_auditorFinalize = audit;
168  m_auditorReinitialize = audit;
169  m_auditorRestart = audit;
170 }
171 
172 //-----------------------------------------------------------------------------
174  //-----------------------------------------------------------------------------
175  return attempt( *this, "sysInitialize", [&]() {
177  Gaudi::Guards::AuditorGuard guard( this,
178  // check if we want to audit the initialize
180  StatusCode sc = initialize();
181  if ( !sc ) return sc;
182 
185 
186  // check for explicit circular data dependencies in declared handles
187  DataObjIDColl out;
188  for ( auto& h : outputHandles() ) {
189  if ( !h->objKey().empty() ) out.emplace( h->fullKey() );
190  }
191  for ( auto& h : inputHandles() ) {
192  if ( !h->objKey().empty() && out.find( h->fullKey() ) != out.end() ) {
193  error() << "Explicit circular data dependency found for id " << h->fullKey() << endmsg;
194  sc = StatusCode::FAILURE;
195  }
196  }
197 
198  if ( !sc ) return sc;
199 
200  // visit all sub-tools, build full set
202  acceptDHVisitor( &avis );
203 
204  // initialize handles
205  initDataHandleHolder(); // this should 'freeze' the handle configuration.
206 
207  return sc;
208  } );
209 }
210 //------------------------------------------------------------------------------
212 //------------------------------------------------------------------------------
213 {
214  // For the time being there is nothing to be done here.
215  // Setting the properties is done by the ToolSvc calling setProperties()
216  // explicitly.
217  return StatusCode::SUCCESS;
218 }
219 
220 //-----------------------------------------------------------------------------
222  //-----------------------------------------------------------------------------
223  return attempt( *this, "sysStart", [&]() {
225  Gaudi::Guards::AuditorGuard guard( this,
226  // check if we want to audit the initialize
227  m_auditorStart ? auditorSvc() : nullptr, IAuditor::Start );
228  StatusCode sc = start();
229  if ( sc.isSuccess() ) m_state = m_targetState;
230  return sc;
231  } );
232 }
233 
234 //------------------------------------------------------------------------------
236 //------------------------------------------------------------------------------
237 {
238  // For the time being there is nothing to be done here.
239  return StatusCode::SUCCESS;
240 }
241 
242 //-----------------------------------------------------------------------------
244  //-----------------------------------------------------------------------------
245  return attempt( *this, "sysStop", [&]() {
247  Gaudi::Guards::AuditorGuard guard( this,
248  // check if we want to audit the initialize
249  m_auditorStop ? auditorSvc() : nullptr, IAuditor::Stop );
250  StatusCode sc = stop();
251  if ( sc.isSuccess() ) m_state = m_targetState;
252  return sc;
253  } );
254 }
255 
256 //------------------------------------------------------------------------------
258 //------------------------------------------------------------------------------
259 {
260  // For the time being there is nothing to be done here.
261  return StatusCode::SUCCESS;
262 }
263 
264 //-----------------------------------------------------------------------------
266  //-----------------------------------------------------------------------------
267  return attempt( *this, "sysFinalize", [&]() {
269  Gaudi::Guards::AuditorGuard guard( this,
270  // check if we want to audit the initialize
272  StatusCode sc = finalize();
273  if ( sc.isSuccess() ) m_state = m_targetState;
274  return sc;
275  } );
276 }
277 //------------------------------------------------------------------------------
279 //------------------------------------------------------------------------------
280 {
281  // For the time being there is nothing to be done here.
282  return StatusCode::SUCCESS;
283 }
284 
285 //-----------------------------------------------------------------------------
287  //-----------------------------------------------------------------------------
288 
289  // Check that the current status is the correct one.
291  error() << "sysReinitialize(): cannot reinitialize tool not initialized" << endmsg;
292  return StatusCode::FAILURE;
293  }
294 
295  return attempt( *this, "SysReinitialize()", [&]() {
296  Gaudi::Guards::AuditorGuard guard( this,
297  // check if we want to audit the initialize
299  return reinitialize();
300  } );
301 }
302 
303 //------------------------------------------------------------------------------
305 //------------------------------------------------------------------------------
306 {
307  /* @TODO
308  * MCl 2008-10-23: the implementation of reinitialize as finalize+initialize
309  * is causing too many problems
310  *
311  // Default implementation is finalize+initialize
312  StatusCode sc = finalize();
313  if (sc.isFailure()) {
314  error() << "reinitialize(): cannot be finalized" << endmsg;
315  return sc;
316  }
317  sc = initialize();
318  if (sc.isFailure()) {
319  error() << "reinitialize(): cannot be initialized" << endmsg;
320  return sc;
321  }
322  */
323  return StatusCode::SUCCESS;
324 }
325 
326 //-----------------------------------------------------------------------------
328  //-----------------------------------------------------------------------------
329 
330  // Check that the current status is the correct one.
332  error() << "sysRestart(): cannot reinitialize tool not started" << endmsg;
333  return StatusCode::FAILURE;
334  }
335 
336  return attempt( *this, "sysRestart", [&]() {
338  Gaudi::Guards::AuditorGuard guard( this,
339  // check if we want to audit the initialize
341  return restart();
342  } );
343 }
344 
345 //------------------------------------------------------------------------------
347 //------------------------------------------------------------------------------
348 {
349  // Default implementation is stop+start
350  StatusCode sc = stop();
351  if ( sc.isFailure() ) {
352  error() << "restart(): cannot be stopped" << endmsg;
353  return sc;
354  }
355  sc = start();
356  if ( sc.isFailure() ) {
357  error() << "restart(): cannot be started" << endmsg;
358  return sc;
359  }
360  return StatusCode::SUCCESS;
361 }
362 
363 //------------------------------------------------------------------------------
365 //------------------------------------------------------------------------------
366 {
367  if ( m_pMonitorSvc ) { m_pMonitorSvc->undeclareAll( this ); }
368 }
369 
371  auto init_one = [&]( BaseToolHandle* th ) {
372  if ( !th->isEnabled() ) {
373  if ( UNLIKELY( msgLevel( MSG::DEBUG ) ) && !th->typeAndName().empty() )
374  debug() << "ToolHandle " << th->typeAndName() << " not used" << endmsg;
375  return;
376  }
377  if ( !th->get() ) {
378  auto sc = th->retrieve();
379  if ( UNLIKELY( sc.isFailure() ) ) {
380  throw GaudiException( "Failed to retrieve tool " + th->typeAndName(), this->name(), StatusCode::FAILURE );
381  }
382  }
383  auto* tool = th->get();
384  if ( UNLIKELY( msgLevel( MSG::DEBUG ) ) )
385  debug() << "Adding " << ( th->isPublic() ? "public" : "private" ) << " ToolHandle tool " << tool->name() << " ("
386  << tool->type() << ")" << endmsg;
387  m_tools.push_back( tool );
388  };
389 
390  for ( auto thArr : m_toolHandleArrays ) {
391  if ( UNLIKELY( msgLevel( MSG::DEBUG ) ) )
392  debug() << "Registering all Tools in ToolHandleArray " << thArr->propertyName() << endmsg;
393  // Iterate over its tools:
394  for ( auto toolHandle : thArr->getBaseArray() ) {
395  // Try to cast it into a BaseToolHandle pointer:
396  BaseToolHandle* bth = dynamic_cast<BaseToolHandle*>( toolHandle );
397  if ( bth ) {
398  init_one( bth );
399  } else {
400  error() << "Error retrieving Tool " << toolHandle->typeAndName() << " in ToolHandleArray "
401  << thArr->propertyName() << ". Not registered" << endmsg;
402  }
403  }
404  }
405 
406  for ( BaseToolHandle* th : m_toolHandles ) init_one( th );
407 
408  m_toolHandlesInit = true;
409 }
410 
413 
414  return m_tools;
415 }
416 
419 
420  return m_tools;
421 }
422 
423 //------------------------------------------------------------------------------
425 StatusCode AlgTool::service_i( std::string_view svcName, bool createIf, const InterfaceID& iid, void** ppSvc ) const {
426  const ServiceLocatorHelper helper( *serviceLocator(), *this );
427  return helper.getService( svcName, createIf, iid, ppSvc );
428 }
429 
430 //------------------------------------------------------------------------------
431 StatusCode AlgTool::service_i( std::string_view svcType, std::string_view svcName, const InterfaceID& iid,
432  void** ppSvc ) const {
433  const ServiceLocatorHelper helper( *serviceLocator(), *this );
434  return helper.createService( svcType, svcName, iid, ppSvc );
435 }
436 
437 SmartIF<IService> AlgTool::service( std::string_view name, const bool createIf, const bool quiet ) const {
438  const ServiceLocatorHelper helper( *serviceLocator(), *this );
439  return helper.service( name, quiet, createIf );
440 }
441 
442 //-----------------------------------------------------------------------------
444  //---------------------------------------------------------------------------
445  if ( !m_pAuditorSvc ) {
446  m_pAuditorSvc = service( "AuditorSvc", true );
447  if ( !m_pAuditorSvc ) { throw GaudiException( "Service [AuditorSvc] not found", name(), StatusCode::FAILURE ); }
448  }
449  return m_pAuditorSvc.get();
450 }
451 
452 //-----------------------------------------------------------------------------
454  //-----------------------------------------------------------------------------
455  vis->visit( this );
456 
457  for ( auto tool : tools() ) vis->visit( dynamic_cast<AlgTool*>( tool ) );
458 }
void initToolHandles() const
Definition: AlgTool.cpp:370
The interface implemented by the IToolSvc base class.
Definition: IToolSvc.h:29
#define UNLIKELY(x)
Definition: Kernel.h:106
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:34
an helper to share the implementation of service() among the various kernel base classes
SmartIF< IMonitorSvc > m_pMonitorSvc
Online Monitoring Service.
Definition: AlgTool.h:295
Define general base for Gaudi exception.
Gaudi::Property< bool > m_auditorStart
Definition: AlgTool.h:312
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
bool m_toolHandlesInit
Definition: AlgTool.h:322
std::string m_type
AlgTool type (concrete class name)
Definition: AlgTool.h:288
Implementation of property with value of concrete type.
Definition: Property.h:370
StatusCode initialize() override
Definition: AlgTool.cpp:211
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:308
SmartIF< IService > service(std::string_view name, const bool quiet=false, const bool createIf=true) const
virtual const std::string & tag() const
name tag for the exception, or exception type
const IInterface * m_parent
AlgTool parent.
Definition: AlgTool.h:290
AlgTool(std::string type, std::string name, const IInterface *parent)
Standard Constructor.
Definition: AlgTool.cpp:128
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
Non-templated base class for actual ToolHandle<T>.
Definition: ToolHandle.h:79
void initDataHandleHolder()
initializes all handles - called by the sysInitialize method of any descendant of this
STL namespace.
StatusCode sysReinitialize() override
Initialize AlgTool.
Definition: AlgTool.cpp:286
T end(T... args)
Gaudi::Property< bool > m_auditorReinitialize
Definition: AlgTool.h:315
Data provider interface definition.
~AlgTool() override
Definition: AlgTool.cpp:364
std::vector< IAlgTool * > m_tools
Definition: AlgTool.h:319
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:86
StatusCode queryInterface(const InterfaceID &riid, void **ppvUnknown) override
Query for a given interface.
Definition: AlgTool.cpp:51
StatusCode setProperties()
Method for setting declared properties to the values specified in the jobOptions via the job option s...
Definition: AlgTool.cpp:117
StatusCode sysStart() override
Start AlgTool.
Definition: AlgTool.cpp:221
Gaudi::StateMachine::State FSMState() const override
Definition: AlgTool.h:84
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
STL class.
StatusCode sysStop() override
Stop AlgTool.
Definition: AlgTool.cpp:243
StatusCode getService(std::string_view name, bool createIf, const InterfaceID &iid, void **ppSvc) const
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: AlgTool.cpp:89
StatusCode finalize() override
Definition: AlgTool.cpp:278
const std::string m_name
AlgTool full name.
Definition: AlgTool.h:289
virtual void visit(const IDataHandleHolder *)=0
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:86
T push_back(T... args)
Interface ID class.
Definition: IInterface.h:39
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Main interface for the JobOptions service.
T what(T... args)
IAuditorSvc * auditorSvc() const
Access the auditor service.
Definition: AlgTool.cpp:443
Gaudi::Property< int > m_outputLevel
Definition: AlgTool.h:302
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:61
Definition of the basic interface.
Definition: IInterface.h:254
virtual bool hasProperty(const std::string &name) const =0
Return true if we have a property with the given name.
Gaudi::Property< bool > m_auditorStop
Definition: AlgTool.h:313
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
StatusCode restart() override
Definition: AlgTool.cpp:346
const std::vector< IAlgTool * > & tools() const
Definition: AlgTool.cpp:411
SmartIF< IToolSvc > m_ptoolSvc
Tool service.
Definition: AlgTool.h:294
bool isSuccess() const
Definition: StatusCode.h:365
STL class.
void acceptDHVisitor(IDataHandleVisitor *) const override
Definition: AlgTool.cpp:453
SmartIF< IAuditorSvc > m_pAuditorSvc
Auditor Service.
Definition: AlgTool.h:296
Gaudi::Property< bool > m_auditorRestart
Definition: AlgTool.h:316
T get(T... args)
T find_if(T... args)
Gaudi::StateMachine::State m_state
state of the Tool
Definition: AlgTool.h:328
State GAUDI_API ChangeState(const Transition transition, const State state)
Function to get the new state according to the required transition, checking if the transition is all...
std::vector< BaseToolHandle * > m_toolHandles
Definition: AlgTool.h:320
T begin(T... args)
Gaudi::Property< bool > m_auditInit
Definition: AlgTool.h:310
StatusCode createService(std::string_view name, const InterfaceID &iid, void **ppSvc) const
StatusCode service(std::string_view name, T *&svc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
Definition: AlgTool.h:138
IToolSvc * toolSvc() const
The standard ToolSvc service, Return a pointer to the service if present.
Definition: AlgTool.cpp:106
Base class from which all the concrete tool classes should be derived.
Definition: AlgTool.h:57
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:89
T emplace(T... args)
SmartIF< ISvcLocator > m_svcLocator
Pointer to Service Locator service.
Definition: AlgTool.h:292
appMgr
Definition: IOTest.py:103
SmartIF< IDataProviderSvc > m_evtSvc
Event data service.
Definition: AlgTool.h:293
constexpr static const auto FAILURE
Definition: StatusCode.h:101
const Gaudi::Algorithm & parent
const std::string & type() const override
Retrieve type (concrete class) of the sub-algtool.
Definition: AlgTool.cpp:75
bool assign(const Details::PropertyBase &source) override
get the value from another property
Definition: Property.h:687
Gaudi::Property< bool > m_auditorInitialize
Definition: AlgTool.h:311
StatusCode reinitialize() override
Definition: AlgTool.cpp:304
InterfaceList m_interfaceList
Interface list.
Definition: AlgTool.h:298
bool isFailure() const
Definition: StatusCode.h:145
StatusCode stop() override
Definition: AlgTool.cpp:257
StatusCode sysInitialize() override
Initialize AlgTool.
Definition: AlgTool.cpp:173
Gaudi::StateMachine::State m_targetState
state of the Tool
Definition: AlgTool.h:329
IDataProviderSvc * evtSvc() const
accessor to event service service
Definition: AlgTool.cpp:98
It is a simple guard, which "locks" the scope for the Auditor Service is am exception-safe way.
Definition: Guards.h:213
The interface implemented by the IAuditorSvc base class.
Definition: IAuditorSvc.h:25
Base class for all services.
Definition: Service.h:46
virtual void undeclareAll(const IInterface *owner)=0
Undeclare monitoring information.
const std::string & name() const override
Retrieve full identifying name of the concrete tool object.
Definition: AlgTool.cpp:68
StatusCode service_i(std::string_view algName, bool createIf, const InterfaceID &iid, void **ppSvc) const
flag indicating whether ToolHandle tools have been added to m_tools
Definition: AlgTool.cpp:425
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
StatusCode sysFinalize() override
Finalize AlgTool.
Definition: AlgTool.cpp:265
std::vector< GaudiHandleArrayBase * > m_toolHandleArrays
Definition: AlgTool.h:321
std::unique_ptr< IDataHandleVisitor > m_updateDataHandles
Hook for for derived classes to provide a custom visitor for data handles.
Definition: AlgTool.h:232
Gaudi::Property< bool > m_auditorFinalize
Definition: AlgTool.h:314
Base class from which all concrete auditor classes should be derived.
Definition: Auditor.h:44
StatusCode sysRestart() override
Start AlgTool.
Definition: AlgTool.cpp:327
StatusCode start() override
Definition: AlgTool.cpp:235
const IInterface * parent() const override
Retrieve parent of the sub-algtool.
Definition: AlgTool.cpp:82