The Gaudi Framework  master (82fdf313)
Loading...
Searching...
No Matches
AlgTool.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 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 <Gaudi/Algorithm.h>
12#include <Gaudi/Auditor.h>
13#include <GaudiKernel/AlgTool.h>
16#include <GaudiKernel/Guards.h>
20#include <GaudiKernel/Service.h>
22#include <GaudiKernel/System.h>
24
25namespace {
26 template <typename FUN>
27 StatusCode attempt( AlgTool& tool, const char* label, FUN&& fun ) {
28 try {
29 return fun();
30 } catch ( const GaudiException& Exception ) {
31 MsgStream log( tool.msgSvc(), tool.name() + "." + label );
32 log << MSG::FATAL << " Exception with tag=" << Exception.tag() << " is caught" << endmsg;
33 log << MSG::ERROR << Exception << endmsg;
34 } catch ( const std::exception& Exception ) {
35 MsgStream log( tool.msgSvc(), tool.name() + "." + label );
36 log << MSG::FATAL << " Standard std::exception is caught" << endmsg;
37 log << MSG::ERROR << Exception.what() << endmsg;
38 } catch ( ... ) {
39 MsgStream log( tool.msgSvc(), tool.name() + "." + label );
40 log << MSG::FATAL << "UNKNOWN Exception is caught" << endmsg;
41 }
43 }
44} // namespace
45
46StatusCode AlgTool::queryInterface( const InterfaceID& riid, void** ppvi ) {
47 if ( !ppvi ) { return StatusCode::FAILURE; }
48 StatusCode sc = base_class::queryInterface( riid, ppvi );
49 if ( sc.isSuccess() ) return sc;
50 auto i = std::find_if( std::begin( m_interfaceList ), std::end( m_interfaceList ),
51 [&]( const std::pair<InterfaceID, void*>& item ) { return item.first.versionMatch( riid ); } );
52 if ( i == std::end( m_interfaceList ) ) {
53 *ppvi = nullptr;
54 return Status::NO_INTERFACE;
55 }
56 *ppvi = i->second;
57 addRef();
59}
60
61void const* AlgTool::i_cast( const InterfaceID& riid ) const {
62 if ( auto output = base_class::i_cast( riid ) ) { return output; }
63 if ( auto i =
64 std::find_if( std::begin( m_interfaceList ), std::end( m_interfaceList ),
65 [&]( const std::pair<InterfaceID, void*>& item ) { return item.first.versionMatch( riid ); } );
66 i != std::end( m_interfaceList ) ) {
67 return i->second;
68 }
69 return nullptr;
70}
71
72const std::string& AlgTool::name() const { return m_name; }
73
74const std::string& AlgTool::type() const { return m_type; }
75
76const IInterface* AlgTool::parent() const { return m_parent; }
77
79
81 if ( !m_evtSvc ) {
82 m_evtSvc = service( "EventDataSvc", true );
83 if ( !m_evtSvc ) { throw GaudiException( "Service [EventDataSvc] not found", name(), StatusCode::FAILURE ); }
84 }
85 return m_evtSvc.get();
86}
88 if ( !m_ptoolSvc ) {
89 m_ptoolSvc = service( "ToolSvc", true );
90 if ( !m_ptoolSvc ) { throw GaudiException( "Service [ToolSvc] not found", name(), StatusCode::FAILURE ); }
91 }
92 return m_ptoolSvc.get();
93}
94
95AlgTool::AlgTool( std::string type, std::string name, const IInterface* parent )
96 : m_type( std::move( type ) ), m_name( std::move( name ) ), m_parent( parent ) {
97 addRef(); // Initial count set to 1
98
99 IInterface* _p = const_cast<IInterface*>( parent );
100
101 if ( Gaudi::Algorithm* _alg = dynamic_cast<Gaudi::Algorithm*>( _p ) ) {
102 m_svcLocator = _alg->serviceLocator();
103 } else if ( Service* _svc = dynamic_cast<Service*>( _p ) ) {
104 m_svcLocator = _svc->serviceLocator();
105 } else if ( AlgTool* _too = dynamic_cast<AlgTool*>( _p ) ) {
106 m_svcLocator = _too->serviceLocator();
107 } else if ( Gaudi::Auditor* _aud = dynamic_cast<Gaudi::Auditor*>( _p ) ) {
108 m_svcLocator = _aud->serviceLocator();
109 } else {
110 throw GaudiException( "Failure to create tool '" + m_type + "/" + m_name + "': illegal parent type '" +
111 System::typeinfoName( typeid( *_p ) ) + "'",
112 "AlgTool", StatusCode::FAILURE );
113 }
114
115 // inherit output level from parent
116 // get the "OutputLevel" property from parent
117 if ( SmartIF<IProperty> pprop( _p ); pprop && pprop->hasProperty( "OutputLevel" ) ) {
118 m_outputLevel.assign( pprop->getProperty( "OutputLevel" ) );
119 }
120
121 // Auditor monitoring properties
122 // Initialize the default value from ApplicationMgr AuditAlgorithms
123 Gaudi::Property<bool> audit( "AuditTools", false );
124 // note that here we need that the service locator is already defined
125 if ( auto appMgr = serviceLocator()->service<IProperty>( "ApplicationMgr" ) ) {
126 appMgr->getProperty( &audit ).ignore();
127 }
128
129 m_auditorInitialize = audit;
130 m_auditorStart = audit;
131 m_auditorStop = audit;
132 m_auditorFinalize = audit;
133 m_auditorReinitialize = audit;
134 m_auditorRestart = audit;
135}
136
138 return attempt( *this, "sysInitialize", [&]() {
141 // check if we want to audit the initialize
143 StatusCode sc = initialize();
144 if ( !sc ) return sc;
145
148
149 // check for explicit circular data dependencies in declared handles
150 DataObjIDColl out;
151 for ( auto& h : outputHandles() ) {
152 if ( !h->objKey().empty() ) out.emplace( h->fullKey() );
153 }
154 for ( auto& h : inputHandles() ) {
155 if ( !h->objKey().empty() && out.find( h->fullKey() ) != out.end() ) {
156 error() << "Explicit circular data dependency found for id " << h->fullKey() << endmsg;
158 }
159 }
160
161 if ( !sc ) return sc;
162
163 // visit all sub-tools, build full set
165 acceptDHVisitor( &avis );
166
167 // initialize handles
168 initDataHandleHolder(); // this should 'freeze' the handle configuration.
169
170 return sc;
171 } );
172}
174 // For the time being there is nothing to be done here.
175 // Setting the properties is done by the ToolSvc calling setProperties()
176 // explicitly.
177 return StatusCode::SUCCESS;
178}
179
181 return attempt( *this, "sysStart", [&]() {
184 // check if we want to audit the initialize
186 StatusCode sc = start();
187 if ( sc.isSuccess() ) m_state = m_targetState;
188 return sc;
189 } );
190}
191
193 // For the time being there is nothing to be done here.
194 return StatusCode::SUCCESS;
195}
196
198 return attempt( *this, "sysStop", [&]() {
201 // check if we want to audit the initialize
203 StatusCode sc = stop();
204 if ( sc.isSuccess() ) m_state = m_targetState;
205 return sc;
206 } );
207}
208
210 // For the time being there is nothing to be done here.
211 return StatusCode::SUCCESS;
212}
213
215 return attempt( *this, "sysFinalize", [&]() {
218 // check if we want to audit the initialize
220 StatusCode sc = finalize();
221 if ( sc.isSuccess() ) m_state = m_targetState;
222 return sc;
223 } );
224}
226 // For the time being there is nothing to be done here.
227 return StatusCode::SUCCESS;
228}
229
231
232 // Check that the current status is the correct one.
234 error() << "sysReinitialize(): cannot reinitialize tool not initialized" << endmsg;
235 return StatusCode::FAILURE;
236 }
237
238 return attempt( *this, "SysReinitialize()", [&]() {
240 // check if we want to audit the initialize
242 return reinitialize();
243 } );
244}
245
247 /* @TODO
248 * MCl 2008-10-23: the implementation of reinitialize as finalize+initialize
249 * is causing too many problems
250 *
251 // Default implementation is finalize+initialize
252 StatusCode sc = finalize();
253 if (sc.isFailure()) {
254 error() << "reinitialize(): cannot be finalized" << endmsg;
255 return sc;
256 }
257 sc = initialize();
258 if (sc.isFailure()) {
259 error() << "reinitialize(): cannot be initialized" << endmsg;
260 return sc;
261 }
262 */
263 return StatusCode::SUCCESS;
264}
265
267
268 // Check that the current status is the correct one.
270 error() << "sysRestart(): cannot reinitialize tool not started" << endmsg;
271 return StatusCode::FAILURE;
272 }
273
274 return attempt( *this, "sysRestart", [&]() {
277 // check if we want to audit the initialize
279 return restart();
280 } );
281}
282
284 // Default implementation is stop+start
285 StatusCode sc = stop();
286 if ( sc.isFailure() ) {
287 error() << "restart(): cannot be stopped" << endmsg;
288 return sc;
289 }
290 sc = start();
291 if ( sc.isFailure() ) {
292 error() << "restart(): cannot be started" << endmsg;
293 return sc;
294 }
295 return StatusCode::SUCCESS;
296}
297
299 if ( m_pMonitorSvc ) { m_pMonitorSvc->undeclareAll( this ); }
300}
301
303 auto init_one = [&]( BaseToolHandle* th ) {
304 if ( !th->isEnabled() ) {
305 if ( msgLevel( MSG::DEBUG ) && !th->typeAndName().empty() )
306 debug() << "ToolHandle " << th->typeAndName() << " not used" << endmsg;
307 return;
308 }
309 if ( !th->get() ) {
310 auto sc = th->retrieve();
311 if ( sc.isFailure() ) {
312 throw GaudiException( "Failed to retrieve tool " + th->typeAndName(), this->name(), StatusCode::FAILURE );
313 }
314 }
315 auto* tool = th->get();
316 if ( msgLevel( MSG::DEBUG ) )
317 debug() << "Adding " << ( th->isPublic() ? "public" : "private" ) << " ToolHandle tool " << tool->name() << " ("
318 << tool->type() << ")" << endmsg;
319 m_tools.push_back( tool );
320 };
321
322 for ( auto thArr : m_toolHandleArrays ) {
323 if ( msgLevel( MSG::DEBUG ) )
324 debug() << "Registering all Tools in ToolHandleArray " << thArr->propertyName() << endmsg;
325 // Iterate over its tools:
326 for ( auto toolHandle : thArr->getBaseArray() ) {
327 // Try to cast it into a BaseToolHandle pointer:
328 BaseToolHandle* bth = dynamic_cast<BaseToolHandle*>( toolHandle );
329 if ( bth ) {
330 init_one( bth );
331 } else {
332 error() << "Error retrieving Tool " << toolHandle->typeAndName() << " in ToolHandleArray "
333 << thArr->propertyName() << ". Not registered" << endmsg;
334 }
335 }
336 }
337
338 for ( BaseToolHandle* th : m_toolHandles ) init_one( th );
339
340 m_toolHandlesInit = true;
341}
342
343const std::vector<IAlgTool*>& AlgTool::tools() const {
345
346 return m_tools;
347}
348
349std::vector<IAlgTool*>& AlgTool::tools() {
351
352 return m_tools;
353}
354
355SmartIF<IService> AlgTool::service( std::string_view name, const bool createIf, const bool quiet ) const {
356 const ServiceLocatorHelper helper( *serviceLocator(), *this );
357 return helper.service( name, quiet, createIf );
358}
359
361 if ( !m_pAuditorSvc ) {
362 m_pAuditorSvc = service( "AuditorSvc", true );
363 if ( !m_pAuditorSvc ) { throw GaudiException( "Service [AuditorSvc] not found", name(), StatusCode::FAILURE ); }
364 }
365 return m_pAuditorSvc.get();
366}
367
369 vis->visit( this );
370
371 for ( auto tool : tools() ) vis->visit( dynamic_cast<AlgTool*>( tool ) );
372}
std::unordered_set< DataObjID, DataObjID_Hasher > DataObjIDColl
Definition DataObjID.h:121
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
Base class from which all the concrete tool classes should be derived.
Definition AlgTool.h:55
std::vector< GaudiHandleArrayBase * > m_toolHandleArrays
Definition AlgTool.h:296
std::unique_ptr< IDataHandleVisitor > m_updateDataHandles
Hook for for derived classes to provide a custom visitor for data handles.
Definition AlgTool.h:209
SmartIF< ISvcLocator > m_svcLocator
Pointer to Service Locator service.
Definition AlgTool.h:268
StatusCode sysFinalize() override
Finalize AlgTool.
Definition AlgTool.cpp:214
StatusCode sysReinitialize() override
Initialize AlgTool.
Definition AlgTool.cpp:230
Gaudi::Property< int > m_outputLevel
Definition AlgTool.h:278
const std::string m_name
AlgTool full name.
Definition AlgTool.h:265
Gaudi::StateMachine::State m_state
flag indicating whether ToolHandle tools have been added to m_tools
Definition AlgTool.h:299
StatusCode queryInterface(const InterfaceID &riid, void **ppvUnknown) override
Query for a given interface.
Definition AlgTool.cpp:46
Gaudi::Property< bool > m_auditorInitialize
Definition AlgTool.h:286
InterfaceList m_interfaceList
Interface list.
Definition AlgTool.h:274
const IInterface * parent() const override
Retrieve parent of the sub-algtool.
Definition AlgTool.cpp:76
StatusCode initialize() override
Definition AlgTool.cpp:173
AlgTool(std::string type, std::string name, const IInterface *parent)
Standard Constructor.
Definition AlgTool.cpp:95
const std::string & type() const override
Retrieve type (concrete class) of the sub-algtool.
Definition AlgTool.cpp:74
~AlgTool() override
Definition AlgTool.cpp:298
const IInterface * m_parent
AlgTool parent.
Definition AlgTool.h:266
SmartIF< IService > service(std::string_view name, const bool createIf=true, const bool quiet=false) const
Return a pointer to the service identified by name (or "type/name")
Definition AlgTool.cpp:355
const std::vector< IAlgTool * > & tools() const
Definition AlgTool.cpp:343
SmartIF< IAuditorSvc > m_pAuditorSvc
Auditor Service.
Definition AlgTool.h:272
const std::string & name() const override
Retrieve full identifying name of the concrete tool object.
Definition AlgTool.cpp:72
std::vector< BaseToolHandle * > m_toolHandles
Definition AlgTool.h:295
Gaudi::Property< bool > m_auditorStart
Definition AlgTool.h:287
IDataProviderSvc * evtSvc() const
accessor to event service service
Definition AlgTool.cpp:80
std::vector< IAlgTool * > m_tools
Definition AlgTool.h:294
IToolSvc * toolSvc() const
The standard ToolSvc service, Return a pointer to the service if present.
Definition AlgTool.cpp:87
bool m_toolHandlesInit
Definition AlgTool.h:297
Gaudi::StateMachine::State FSMState() const override
Definition AlgTool.h:84
StatusCode reinitialize() override
Definition AlgTool.cpp:246
Gaudi::Property< bool > m_auditorStop
Definition AlgTool.h:288
Gaudi::Property< bool > m_auditorReinitialize
Definition AlgTool.h:290
SmartIF< IDataProviderSvc > m_evtSvc
Event data service.
Definition AlgTool.h:269
std::string m_type
AlgTool type (concrete class name)
Definition AlgTool.h:264
StatusCode sysRestart() override
Start AlgTool.
Definition AlgTool.cpp:266
StatusCode restart() override
Definition AlgTool.cpp:283
StatusCode start() override
Definition AlgTool.cpp:192
void initToolHandles() const
Definition AlgTool.cpp:302
void acceptDHVisitor(IDataHandleVisitor *) const override
Definition AlgTool.cpp:368
StatusCode sysStart() override
Start AlgTool.
Definition AlgTool.cpp:180
SmartIF< IMonitorSvc > m_pMonitorSvc
Online Monitoring Service.
Definition AlgTool.h:271
Gaudi::Property< bool > m_auditorFinalize
Definition AlgTool.h:289
StatusCode sysInitialize() override
Initialize AlgTool.
Definition AlgTool.cpp:137
IAuditorSvc * auditorSvc() const
Access the auditor service.
Definition AlgTool.cpp:360
StatusCode stop() override
Definition AlgTool.cpp:209
StatusCode sysStop() override
Stop AlgTool.
Definition AlgTool.cpp:197
Gaudi::Property< bool > m_auditorRestart
Definition AlgTool.h:291
Gaudi::StateMachine::State m_targetState
state of the Tool
Definition AlgTool.h:300
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition AlgTool.cpp:78
StatusCode finalize() override
Definition AlgTool.cpp:225
SmartIF< IToolSvc > m_ptoolSvc
Tool service.
Definition AlgTool.h:270
void const * i_cast(const InterfaceID &riid) const override
Definition AlgTool.cpp:61
Non-templated base class for actual ToolHandle<T>.
Definition ToolHandle.h:78
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Base class from which all concrete algorithm classes should be derived.
Definition Algorithm.h:87
Base class from which all concrete auditor classes should be derived.
Definition Auditor.h:33
It is a simple guard, which "locks" the scope for the Auditor Service is am exception-safe way.
Definition Guards.h:202
static const std::string Stop
Definition IAuditor.h:52
static const std::string Initialize
Definition IAuditor.h:47
static const std::string Finalize
Definition IAuditor.h:53
static const std::string Start
Definition IAuditor.h:49
static const std::string ReInitialize
Definition IAuditor.h:48
static const std::string ReStart
Definition IAuditor.h:50
Implementation of property with value of concrete type.
Definition PropertyFwd.h:27
bool assign(const Details::PropertyBase &source) override
get the value from another property
Definition Property.h:361
Define general base for Gaudi exception.
The interface implemented by the IAuditorSvc base class.
Definition IAuditorSvc.h:24
virtual void visit(const IDataHandleHolder *)=0
Data provider interface definition.
Definition of the basic interface.
Definition IInterface.h:225
The interface implemented by the IToolSvc base class.
Definition IToolSvc.h:28
Interface ID class.
Definition IInterface.h:38
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
Base class for all services.
Definition Service.h:39
an helper to share the implementation of service() among the various kernel base classes
SmartIF< IService > service(std::string_view name, const bool quiet=false, const bool createIf=true) const
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isFailure() const
Definition StatusCode.h:129
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
void const * i_cast(const InterfaceID &tid) const override
Implementation of IInterface::i_cast.
Definition extends.h:30
StatusCode queryInterface(const InterfaceID &ti, void **pp) override
Implementation of IInterface::queryInterface.
Definition extends.h:37
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...
@ FATAL
Definition IMessageSvc.h:22
@ DEBUG
Definition IMessageSvc.h:22
@ ERROR
Definition IMessageSvc.h:22
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260
STL namespace.