The Gaudi Framework  v41r0 (bdbe7744)
Loading...
Searching...
No Matches
MinimalEventLoopMgr.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#define GAUDIKERNEL_MINIMALEVENTLOOPMGR_CPP
12
21#include <GaudiKernel/SmartIF.h>
24
26
27#include <algorithm>
28
29#define ON_DEBUG if ( outputLevel() <= MSG::DEBUG )
30#define ON_VERBOSE if ( outputLevel() <= MSG::VERBOSE )
31
32#define DEBMSG ON_DEBUG debug()
33#define VERMSG ON_VERBOSE verbose()
34
35//--------------------------------------------------------------------------------------------
36// Standard Constructor
37//--------------------------------------------------------------------------------------------
38MinimalEventLoopMgr::MinimalEventLoopMgr( const std::string& nam, ISvcLocator* svcLoc )
39 : base_class( nam, svcLoc ), m_appMgrUI( svcLoc ) {}
40
41//--------------------------------------------------------------------------------------------
42// implementation of IAppMgrUI::initialize
43//--------------------------------------------------------------------------------------------
45
46 if ( !m_appMgrUI ) return StatusCode::FAILURE;
47
49 if ( !sc.isSuccess() ) {
50 error() << "Failed to initialize Service Base class." << endmsg;
52 }
53
54 auto prpMgr = serviceLocator()->as<IProperty>();
55 if ( !prpMgr ) {
56 error() << "Error retrieving AppMgr interface IProperty." << endmsg;
58 }
59 if ( m_topAlgNames.value().empty() ) { setProperty( prpMgr->getProperty( "TopAlg" ) ).ignore(); }
60 if ( m_outStreamNames.value().empty() ) { setProperty( prpMgr->getProperty( "OutStream" ) ).ignore(); }
61
62 // Get the references to the services that are needed by the ApplicationMgr itself
63 m_incidentSvc = serviceLocator()->service( "IncidentSvc" );
64 if ( !m_incidentSvc ) {
65 fatal() << "Error retrieving IncidentSvc." << endmsg;
67 }
68
69 m_incidentSvc->addListener( &m_abortEventListener, IncidentType::AbortEvent );
70
71 // The state is changed at this moment to allow decodeXXXX() to do something
73
74 // Get WhiteBoard interface if implemented by EventDataSvc
75 m_WB = service( "EventDataSvc" );
76
77 // setup the default EventContext with slot 0
79
80 //--------------------------------------------------------------------------------------------
81 // Create output streams. Do not initialize them yet.
82 // The state is updated temporarily in order to enable the handler, which
83 // is also triggered by a change to the "OutputStream" Property.
84 //--------------------------------------------------------------------------------------------
86 if ( !sc.isSuccess() ) {
87 error() << "Failed to initialize Output streams." << endmsg;
89 return sc;
90 }
91 //--------------------------------------------------------------------------------------------
92 // Create all needed Top Algorithms. Do not initialize them yet.
93 // The state is updated temporarily in order to enable the handler, which
94 // is also triggered by a change to the "TopAlg" Property.
95 //--------------------------------------------------------------------------------------------
96 sc = decodeTopAlgs();
97 if ( !sc.isSuccess() ) {
98 error() << "Failed to initialize Top Algorithms streams." << endmsg;
100 return sc;
101 }
102
103 // Initialize all the new TopAlgs. In fact Algorithms are protected against
104 // getting initialized twice.
105 for ( auto& ita : m_topAlgList ) {
106 sc = ita->sysInitialize();
107 if ( !sc.isSuccess() ) {
108 error() << "Unable to initialize Algorithm: " << ita->name() << endmsg;
109 return sc;
110 }
111 }
112 for ( auto& ita : m_outStreamList ) {
113 sc = ita->sysInitialize();
114 if ( !sc.isSuccess() ) {
115 error() << "Unable to initialize Output Stream: " << ita->name() << endmsg;
116 return sc;
117 }
118 }
119
120 // get hold of the Algorithm Execution State mgr
121 m_aess = serviceLocator()->service( "AlgExecStateSvc" );
122 if ( !m_aess ) {
123 fatal() << "Error retrieving AlgExecStateSvc." << endmsg;
124 return StatusCode::FAILURE;
125 }
126
127 if ( m_printCFExp && !m_topAlgList.empty() ) {
128 info() << "Control Flow Expression:" << endmsg;
129 std::stringstream expr;
130 auto& first = m_topAlgList.front();
131 for ( auto& ialg : m_topAlgList ) {
132 if ( ialg != first ) expr << " >> ";
133 ialg->toControlFlowExpression( expr );
134 }
135 info() << expr.str() << endmsg;
136 }
137 return StatusCode::SUCCESS;
138}
139//--------------------------------------------------------------------------------------------
140// implementation of IAppMgrUI::start
141//--------------------------------------------------------------------------------------------
143
145 if ( !sc.isSuccess() ) return sc;
146
147 // Start all the new TopAlgs. In fact Algorithms are protected against getting
148 // started twice.
149 for ( auto& ita : m_topAlgList ) {
150 sc = ita->sysStart();
151 if ( !sc.isSuccess() ) {
152 error() << "Unable to start Algorithm: " << ita->name() << endmsg;
153 return sc;
154 }
155 }
156 for ( auto& ita : m_outStreamList ) {
157 sc = ita->sysStart();
158 if ( !sc.isSuccess() ) {
159 error() << "Unable to start Output Stream: " << ita->name() << endmsg;
160 return sc;
161 }
162 }
163 return StatusCode::SUCCESS;
164}
165//--------------------------------------------------------------------------------------------
166// implementation of IAppMgrUI::stop
167//--------------------------------------------------------------------------------------------
169
171
172 // Stop all the TopAlgs. In fact Algorithms are protected against getting
173 // stopped twice.
174 for ( auto& ita : m_topAlgList ) {
175 sc = ita->sysStop();
176 if ( !sc.isSuccess() ) {
177 error() << "Unable to stop Algorithm: " << ita->name() << endmsg;
178 return sc;
179 }
180 }
181 for ( auto& ita : m_outStreamList ) {
182 sc = ita->sysStop();
183 if ( !sc.isSuccess() ) {
184 error() << "Unable to stop Output Stream: " << ita->name() << endmsg;
185 return sc;
186 }
187 }
188
189 return Service::stop();
190}
191
192//--------------------------------------------------------------------------------------------
193// implementation of IService::reinitialize
194//--------------------------------------------------------------------------------------------
197
198 // Reinitialize all the TopAlgs.
199 for ( auto& ita : m_topAlgList ) {
200 sc = ita->sysReinitialize();
201 if ( !sc.isSuccess() ) {
202 error() << "Unable to reinitialize Algorithm: " << ita->name() << endmsg;
203 return sc;
204 }
205 }
206 for ( auto& ita : m_outStreamList ) {
207 sc = ita->sysReinitialize();
208 if ( !sc.isSuccess() ) {
209 error() << "Unable to reinitialize Output Stream: " << ita->name() << endmsg;
210 return sc;
211 }
212 }
213
214 return sc;
215}
216//--------------------------------------------------------------------------------------------
217// implementation of IService::restart
218//--------------------------------------------------------------------------------------------
221
222 // Restart all the TopAlgs.
223 for ( auto& ita : m_topAlgList ) {
224 m_aess->resetErrorCount( ita );
225 sc = ita->sysRestart();
226 if ( !sc.isSuccess() ) {
227 error() << "Unable to restart Algorithm: " << ita->name() << endmsg;
228 return sc;
229 }
230 }
231 for ( auto& ita : m_outStreamList ) {
232 m_aess->resetErrorCount( ita );
233 sc = ita->sysRestart();
234 if ( !sc.isSuccess() ) {
235 error() << "Unable to restart Output Stream: " << ita->name() << endmsg;
236 return sc;
237 }
238 }
239
240 return sc;
241}
242
243//--------------------------------------------------------------------------------------------
244// implementation of IService::finalize
245//--------------------------------------------------------------------------------------------
249 // Call the finalize() method of all top algorithms
250 for ( auto& ita : m_topAlgList ) {
251 sc = ita->sysFinalize();
252 if ( !sc.isSuccess() ) {
253 scRet = StatusCode::FAILURE;
254 warning() << "Finalization of algorithm " << ita->name() << " failed" << endmsg;
255 }
256 }
257 // Call the finalize() method of all Output streams
258 for ( auto& ita : m_outStreamList ) {
259 sc = ita->sysFinalize();
260 if ( !sc.isSuccess() ) {
261 scRet = StatusCode::FAILURE;
262 warning() << "Finalization of algorithm " << ita->name() << " failed" << endmsg;
263 }
264 }
265 // release all top algorithms
266 auto algMan = serviceLocator()->as<IAlgManager>();
267 for ( auto& ita : m_topAlgList ) {
268 if ( algMan->removeAlgorithm( ita ).isFailure() ) {
269 scRet = StatusCode::FAILURE;
270 warning() << "Problems removing Algorithm " << ita->name() << endmsg;
271 }
272 }
273 m_topAlgList.clear();
274 m_outStreamList.clear();
275 if ( sc.isSuccess() ) m_state = FINALIZED;
276
277 m_incidentSvc->removeListener( &m_abortEventListener, IncidentType::AbortEvent );
278
279 m_incidentSvc.reset();
280 m_appMgrUI.reset();
281
282 sc = Service::finalize();
283
284 if ( sc.isFailure() ) {
285 scRet = StatusCode::FAILURE;
286 error() << "Problems finalizing Service base class" << endmsg;
287 }
288
289 return scRet;
290}
291
293//--------------------------------------------------------------------------------------------
294// implementation of IAppMgrUI::nextEvent
295//--------------------------------------------------------------------------------------------
297 error() << "This method cannot be called on an object of type " << System::typeinfoName( typeid( *this ) ) << endmsg;
298 return StatusCode::FAILURE;
299}
300
301//--------------------------------------------------------------------------------------------
302// IEventProcessing::executeRun
303//--------------------------------------------------------------------------------------------
305 // Call now the nextEvent(...)
306 return nextEvent( maxevt );
307}
308
309namespace {
312 class RetCodeGuard {
313 public:
314 inline RetCodeGuard( SmartIF<IProperty> appmgr, int retcode )
315 : m_appmgr( std::move( appmgr ) ), m_retcode( retcode ) {}
316 inline void ignore() { m_retcode = Gaudi::ReturnCode::Success; }
317 inline ~RetCodeGuard() {
319 }
320
321 private:
322 SmartIF<IProperty> m_appmgr;
323 int m_retcode;
324 };
325} // namespace
326//--------------------------------------------------------------------------------------------
327// Implementation of IEventProcessor::executeEvent(void* par)
328//--------------------------------------------------------------------------------------------
330 bool eventfailed = false;
331
332 m_aess->reset( context );
333
334 // select the appropriate store
335 if ( m_WB.isValid() ) m_WB->selectStore( context.slot() ).ignore();
336
337 // Get the IProperty interface of the ApplicationMgr to pass it to RetCodeGuard
338 const auto appmgr = serviceLocator()->as<IProperty>();
339 // Call the execute() method of all top algorithms
340 for ( auto& ita : m_topAlgList ) {
342 try {
343 if ( m_abortEventListener.abortEvent ) {
344 DEBMSG << "AbortEvent incident fired by " << m_abortEventListener.abortEventSource << endmsg;
345 m_abortEventListener.abortEvent = false;
346 sc.ignore();
347 break;
348 }
350 sc = ita->sysExecute( context );
351 rcg.ignore(); // disarm the guard
352 } catch ( const GaudiException& Exception ) {
353 fatal() << ".executeEvent(): Exception with tag=" << Exception.tag() << " thrown by " << ita->name() << endmsg;
354 error() << Exception << endmsg;
355 } catch ( const std::exception& Exception ) {
356 fatal() << ".executeEvent(): Standard std::exception thrown by " << ita->name() << endmsg;
357 error() << Exception.what() << endmsg;
358 } catch ( ... ) { fatal() << ".executeEvent(): UNKNOWN Exception thrown by " << ita->name() << endmsg; }
359
360 if ( !sc.isSuccess() ) {
361 warning() << "Execution of algorithm " << ita->name() << " failed" << endmsg;
362 eventfailed = true;
363 }
364 }
365
366 m_aess->updateEventStatus( eventfailed, context );
367
368 // ensure that the abortEvent flag is cleared before the next event
369 if ( m_abortEventListener.abortEvent ) {
370 DEBMSG << "AbortEvent incident fired by " << m_abortEventListener.abortEventSource << endmsg;
371 m_abortEventListener.abortEvent = false;
372 }
373
374 // Call the execute() method of all output streams
375 for ( auto& ito : m_outStreamList ) {
376 AlgExecStateRef state = m_aess->algExecState( ito, context );
377 state.setFilterPassed( true );
378 StatusCode sc = ito->sysExecute( context );
379 if ( !sc.isSuccess() ) {
380 warning() << "Execution of output stream " << ito->name() << " failed" << endmsg;
381 eventfailed = true;
382 }
383 }
384
385 // Check if there was an error processing current event
386 if ( eventfailed ) {
387 error() << "Error processing event loop." << endmsg;
388 std::ostringstream ost;
389 m_aess->dump( ost, context );
390 debug() << "Dumping AlgExecStateSvc status:\n" << ost.str() << endmsg;
391 return StatusCode::FAILURE;
392 }
393
394 return StatusCode::SUCCESS;
395}
396//--------------------------------------------------------------------------------------------
397// Implementation of IEventProcessor::stopRun()
398//--------------------------------------------------------------------------------------------
400 // Set the application return code
401 auto appmgr = serviceLocator()->as<IProperty>();
402 if ( Gaudi::setAppReturnCode( appmgr, Gaudi::ReturnCode::ScheduledStop ).isFailure() ) {
403 error() << "Could not set return code of the application (" << Gaudi::ReturnCode::ScheduledStop << ")" << endmsg;
404 }
405 m_scheduledStop = true;
406 return StatusCode::SUCCESS;
407}
408
409//--------------------------------------------------------------------------------------------
410// Top algorithm List handler
411//--------------------------------------------------------------------------------------------
413 if ( !( decodeTopAlgs() ).isSuccess() ) {
414 throw GaudiException( "Failed to initialize Top Algorithms streams.", "MinimalEventLoopMgr::topAlgHandler",
416 }
417}
418
419//--------------------------------------------------------------------------------------------
420// decodeTopAlgNameList & topAlgNameListHandler
421//--------------------------------------------------------------------------------------------
424 if ( CONFIGURED == m_state || INITIALIZED == m_state ) {
425 auto algMan = serviceLocator()->as<IAlgManager>();
426 if ( algMan ) {
427 // Reset the existing Top Algorithm List
428 m_topAlgList.clear();
429 m_topAlgList.reserve( m_topAlgNames.value().size() );
430 for ( const auto& it : m_topAlgNames.value() ) {
432 // Got the type and name. Now creating the algorithm, avoiding duplicate creation.
433 std::string item_name = item.name();
434 const bool CREATE = false;
435 SmartIF<IAlgorithm> alg = algMan->algorithm( item_name, CREATE );
436 if ( alg ) {
437 DEBMSG << "Top Algorithm " << item_name << " already exists" << endmsg;
438 } else {
439 DEBMSG << "Creating Top Algorithm " << item.type() << " with name " << item_name << endmsg;
440 IAlgorithm* ialg = nullptr;
441 StatusCode sc1 = algMan->createAlgorithm( item.type(), item_name, ialg );
442 if ( !sc1.isSuccess() ) {
443 error() << "Unable to create Top Algorithm " << item.type() << " with name " << item_name << endmsg;
444 return sc1;
445 }
446 alg = ialg; // manage reference counting
447 }
448 m_topAlgList.push_back( alg );
449 }
450 return sc;
451 }
453 }
454 return sc;
455}
456
457//--------------------------------------------------------------------------------------------
458// Output stream List handler
459//--------------------------------------------------------------------------------------------
461 if ( !( decodeOutStreams() ).isSuccess() ) {
462 throw GaudiException( "Failed to initialize output streams.", "MinimalEventLoopMgr::outStreamHandler",
464 }
465}
466
467//--------------------------------------------------------------------------------------------
468// decodeOutStreamNameList & outStreamNameListHandler
469//--------------------------------------------------------------------------------------------
472 if ( CONFIGURED == m_state || INITIALIZED == m_state ) {
473 auto algMan = serviceLocator()->as<IAlgManager>();
474 if ( algMan ) {
475 // Reset the existing Top Algorithm List
476 m_outStreamList.clear();
477 for ( const auto& it : m_outStreamNames.value() ) {
479 const bool CREATE = false;
480 SmartIF<IAlgorithm> os = algMan->algorithm( item, CREATE );
481 if ( os ) {
482 DEBMSG << "Output Stream " << item.name() << " already exists" << endmsg;
483 } else {
484 DEBMSG << "Creating Output Stream " << it << endmsg;
485 IAlgorithm* ios = nullptr;
486 StatusCode sc1 = algMan->createAlgorithm( item.type(), item.name(), ios );
487 if ( !sc1.isSuccess() ) {
488 error() << "Unable to create Output Stream " << it << endmsg;
489 return sc1;
490 }
491 os = ios; // manage reference counting
492 }
493 m_outStreamList.push_back( os );
494 }
495 return sc;
496 }
498 }
499 return sc;
500}
#define DEBMSG
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
wrapper on an Algorithm state.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
This class represents an entry point to all the event specific data.
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
Helper class to parse a string of format "type/name".
const std::string & type() const
const std::string & name() const
Define general base for Gaudi exception.
The IAlgManager is the interface implemented by the Algorithm Factory in the Application Manager to s...
Definition IAlgManager.h:34
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition IAlgorithm.h:37
The IProperty is the basic interface for all components which have properties that can be set or get.
Definition IProperty.h:32
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
virtual SmartIF< IService > & service(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
SmartIF< IFace > as()
Definition ISvcLocator.h:64
StatusCode stop() override
implementation of IService::stop
Gaudi::Property< std::vector< std::string > > m_outStreamNames
StatusCode restart() override
implementation of IService::restart
StatusCode nextEvent(int maxevt) override
implementation of IEventProcessor::nextEvent
StatusCode start() override
implementation of IService::start
void outStreamHandler(Gaudi::Details::PropertyBase &p)
Output stream List handler.
Gaudi::Property< bool > m_printCFExp
StatusCode executeRun(int maxevt) override
implementation of IEventProcessor::executeRun( )
bool m_scheduledStop
Scheduled stop of event processing.
MinimalEventLoopMgr(const std::string &nam, ISvcLocator *svcLoc)
Standard Constructor.
ListAlg m_outStreamList
List of output streams.
StatusCode decodeTopAlgs()
decodeTopAlgNameList & topAlgNameListHandler
Gaudi::Property< std::vector< std::string > > m_topAlgNames
EventContext createEventContext() override
implementation of IEventProcessor::createEventContext()
SmartIF< IAppMgrUI > m_appMgrUI
Reference to the IAppMgrUI interface of the application manager.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to the incident service.
StatusCode finalize() override
implementation of IService::finalize
void topAlgHandler(Gaudi::Details::PropertyBase &p)
Top algorithm List handler.
StatusCode decodeOutStreams()
decodeOutStreamNameList & outStreamNameListHandler
AbortEventListener m_abortEventListener
Instance of the incident listener waiting for AbortEvent.
StatusCode executeEvent(EventContext &&ctx) override
implementation of IEventProcessor::executeEvent(EventContext&&)
SmartIF< IAlgExecStateSvc > m_aess
List of top level algorithms.
StatusCode initialize() override
implementation of IService::initialize
StatusCode reinitialize() override
implementation of IService::reinitialize
SmartIF< IHiveWhiteBoard > m_WB
< Event data service (whiteboard)
State m_state
State of the object.
StatusCode stopRun() override
implementation of IEventProcessor::stopRun( )
Helper class to set the application return code in case of early exit (e.g.
RetCodeGuard(const SmartIF< IProperty > &appmgr, int retcode)
SmartIF< IProperty > m_appmgr
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition Service.cpp:336
StatusCode finalize() override
Definition Service.cpp:223
StatusCode stop() override
Definition Service.cpp:181
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
Definition Service.h:79
StatusCode start() override
Definition Service.cpp:187
StatusCode initialize() override
Definition Service.cpp:118
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:118
void ignore() const
Allow discarding a StatusCode without warning.
Definition StatusCode.h:128
bool isSuccess() const
Definition StatusCode.h:302
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
constexpr int ScheduledStop
constexpr int UnhandledException
GAUDI_API void setCurrentContextId(ContextIdType newId)
Used by the framework to change the value of the current context id.
std::size_t ContextIdType
Internal type used for the ContextId.
constexpr int Success
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:254
STL namespace.