| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MinimalEventLoopMgr.cpp
Go to the documentation of this file.
1 #define GAUDIKERNEL_MINIMALEVENTLOOPMGR_CPP
2
3 #include "GaudiKernel/SmartIF.h"
4 #include "GaudiKernel/MsgStream.h"
5 #include "GaudiKernel/IAlgorithm.h"
6 #include "GaudiKernel/IAlgManager.h"
7 #include "GaudiKernel/TypeNameString.h"
8 #include "GaudiKernel/GaudiException.h"
9 #include "GaudiKernel/ThreadGaudi.h"
10 #include "GaudiKernel/Incident.h"
11 #include "GaudiKernel/IIncidentListener.h"
12 #include "GaudiKernel/IIncidentSvc.h"
13 #include "GaudiKernel/AppReturnCode.h"
14
15 #include "GaudiKernel/MinimalEventLoopMgr.h"
16
17 namespace {
18 class AbortEventListener: public implements1<IIncidentListener> {
19 public:
20 AbortEventListener(bool &flag, std::string &source):m_flag(flag),
21 m_source(source){
22 addRef(); // Initial count set to 1
23 }
24 virtual ~AbortEventListener() {}
26 virtual void handle(const Incident& i) {
27 if (i.type() == IncidentType::AbortEvent) {
28 m_flag = true;
29 m_source = i.source();
30 }
31 }
32
33 private:
35 bool &m_flag;
37 std::string &m_source;
38 };
39 }
40
41 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
42 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
43
44 #define DEBMSG ON_DEBUG debug()
45 #define VERMSG ON_VERBOSE verbose()
46
47 //--------------------------------------------------------------------------------------------
48 // Standard Constructor
49 //--------------------------------------------------------------------------------------------
50 MinimalEventLoopMgr::MinimalEventLoopMgr(const std::string& nam, ISvcLocator* svcLoc)
51 : base_class(nam, svcLoc), m_appMgrUI(svcLoc)
52 {
53 declareProperty("TopAlg", m_topAlgNames );
54 declareProperty("OutStream", m_outStreamNames );
55 declareProperty("OutStreamType", m_outStreamType = "OutputStream");
56 m_topAlgNames.declareUpdateHandler ( &MinimalEventLoopMgr::topAlgHandler, this );
57 m_outStreamNames.declareUpdateHandler( &MinimalEventLoopMgr::outStreamHandler, this );
58 m_state = OFFLINE;
59 m_scheduledStop = false;
60 m_abortEvent = false;
61 }
62
63 //--------------------------------------------------------------------------------------------
64 // Standard Destructor
65 //--------------------------------------------------------------------------------------------
66 MinimalEventLoopMgr::~MinimalEventLoopMgr() {
67 m_state = OFFLINE;
68 }
69
70 //--------------------------------------------------------------------------------------------
71 // implementation of IAppMgrUI::initialize
72 //--------------------------------------------------------------------------------------------
73 StatusCode MinimalEventLoopMgr::initialize() {
74
75 if ( !m_appMgrUI.isValid() ) {
76 return StatusCode::FAILURE;
77 }
78
79 StatusCode sc = Service::initialize();
80 if ( !sc.isSuccess() ) {
81 error() << "Failed to initialize Service Base class." << endmsg;
82 return StatusCode::FAILURE;
83 }
84
85 SmartIF<IProperty> prpMgr(serviceLocator());
86 if ( ! prpMgr.isValid() ) {
87 error() << "Error retrieving AppMgr interface IProperty." << endmsg;
88 return StatusCode::FAILURE;
89 }
90 else {
91 if ( m_topAlgNames.value().size() == 0 ) {
92 setProperty(prpMgr->getProperty("TopAlg")).ignore();
93 }
94 if ( m_outStreamNames.value().size() == 0 ) {
95 setProperty(prpMgr->getProperty("OutStream")).ignore();
96 }
97 }
98
99 // Get the references to the services that are needed by the ApplicationMgr itself
100 m_incidentSvc = serviceLocator()->service("IncidentSvc");
101 if( !m_incidentSvc.isValid() ) {
102 fatal() << "Error retrieving IncidentSvc." << endmsg;
103 return StatusCode::FAILURE;
104 }
105
106 m_abortEventListener = new AbortEventListener(m_abortEvent,m_abortEventSource);
107 m_incidentSvc->addListener(m_abortEventListener,IncidentType::AbortEvent);
108
109 // The state is changed at this moment to allow decodeXXXX() to do something
110 m_state = INITIALIZED;
111
112 //--------------------------------------------------------------------------------------------
113 // Create output streams. Do not initialize them yet.
114 // The state is updated temporarily in order to enable the handler, which
115 // is also triggered by a change to the "OutputStream" Property.
116 //--------------------------------------------------------------------------------------------
117 sc = decodeOutStreams();
118 if ( !sc.isSuccess() ) {
119 error() << "Failed to initialize Output streams." << endmsg;
120 m_state = CONFIGURED;
121 return sc;
122 }
123 //--------------------------------------------------------------------------------------------
124 // Create all needed Top Algorithms. Do not initialize them yet.
125 // The state is updated temporarily in order to enable the handler, which
126 // is also triggered by a change to the "TopAlg" Property.
127 //--------------------------------------------------------------------------------------------
128 sc = decodeTopAlgs();
129 if ( !sc.isSuccess() ) {
130 error() << "Failed to initialize Top Algorithms streams." << endmsg;
131 m_state = CONFIGURED;
132 return sc;
133 }
134
135 ListAlg::iterator ita;
136 // Initialize all the new TopAlgs. In fact Algorithms are protected against getting
137 // initialized twice.
138 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
139 sc = (*ita)->sysInitialize();
140 if( !sc.isSuccess() ) {
141 error() << "Unable to initialize Algorithm: " << (*ita)->name() << endmsg;
142 return sc;
143 }
144 }
145 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
146 sc = (*ita)->sysInitialize();
147 if( !sc.isSuccess() ) {
148 error() << "Unable to initialize Output Stream: " << (*ita)->name() << endmsg;
149 return sc;
150 }
151 }
152
153 return StatusCode::SUCCESS;
154 }
155 //--------------------------------------------------------------------------------------------
156 // implementation of IAppMgrUI::start
157 //--------------------------------------------------------------------------------------------
158 StatusCode MinimalEventLoopMgr::start() {
159
160 StatusCode sc = Service::start();
161 if ( ! sc.isSuccess() ) return sc;
162
163 ListAlg::iterator ita;
164 // Start all the new TopAlgs. In fact Algorithms are protected against getting
165 // started twice.
166 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
167 sc = (*ita)->sysStart();
168 if( !sc.isSuccess() ) {
169 error() << "Unable to start Algorithm: " << (*ita)->name() << endmsg;
170 return sc;
171 }
172 }
173 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
174 sc = (*ita)->sysStart();
175 if( !sc.isSuccess() ) {
176 error() << "Unable to start Output Stream: " << (*ita)->name() << endmsg;
177 return sc;
178 }
179 }
180 return StatusCode::SUCCESS;
181 }
182 //--------------------------------------------------------------------------------------------
183 // implementation of IAppMgrUI::stop
184 //--------------------------------------------------------------------------------------------
185 StatusCode MinimalEventLoopMgr::stop() {
186
187 StatusCode sc = StatusCode::SUCCESS;
188
189 ListAlg::iterator ita;
190 // Stop all the TopAlgs. In fact Algorithms are protected against getting
191 // stopped twice.
192 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
193 sc = (*ita)->sysStop();
194 if( !sc.isSuccess() ) {
195 error() << "Unable to stop Algorithm: " << (*ita)->name() << endmsg;
196 return sc;
197 }
198 }
199 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
200 sc = (*ita)->sysStop();
201 if( !sc.isSuccess() ) {
202 error() << "Unable to stop Output Stream: " << (*ita)->name() << endmsg;
203 return sc;
204 }
205 }
206
207 return Service::stop();
208 }
209
210 //--------------------------------------------------------------------------------------------
211 // implementation of IService::reinitialize
212 //--------------------------------------------------------------------------------------------
213 StatusCode MinimalEventLoopMgr::reinitialize() {
214 StatusCode sc = StatusCode::SUCCESS;
215 ListAlg::iterator ita;
216
217 // Reinitialize all the TopAlgs.
218 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
219 sc = (*ita)->sysReinitialize();
220 if( !sc.isSuccess() ) {
221 error() << "Unable to reinitialize Algorithm: " << (*ita)->name() << endmsg;
222 return sc;
223 }
224 }
225 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
226 sc = (*ita)->sysReinitialize();
227 if( !sc.isSuccess() ) {
228 error() << "Unable to reinitialize Output Stream: " << (*ita)->name() << endmsg;
229 return sc;
230 }
231 }
232
233 return sc;
234 }
235 //--------------------------------------------------------------------------------------------
236 // implementation of IService::restart
237 //--------------------------------------------------------------------------------------------
238 StatusCode MinimalEventLoopMgr::restart() {
239 StatusCode sc = StatusCode::SUCCESS;
240 ListAlg::iterator ita;
241
242 // Restart all the TopAlgs.
243 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
244 sc = (*ita)->sysRestart();
245 if( !sc.isSuccess() ) {
246 error() << "Unable to restart Algorithm: " << (*ita)->name() << endmsg;
247 return sc;
248 }
249 }
250 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
251 sc = (*ita)->sysRestart();
252 if( !sc.isSuccess() ) {
253 error() << "Unable to restart Output Stream: " << (*ita)->name() << endmsg;
254 return sc;
255 }
256 }
257
258 return sc;
259 }
260
261 //--------------------------------------------------------------------------------------------
262 // implementation of IService::finalize
263 //--------------------------------------------------------------------------------------------
264 StatusCode MinimalEventLoopMgr::finalize() {
265 StatusCode sc = StatusCode::SUCCESS;
266 StatusCode scRet = StatusCode::SUCCESS;
267 // Call the finalize() method of all top algorithms
268 ListAlg::iterator ita;
269 for ( ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
270 sc = (*ita)->sysFinalize();
271 if( !sc.isSuccess() ) {
272 scRet = StatusCode::FAILURE;
273 warning() << "Finalization of algorithm " << (*ita)->name() << " failed" << endmsg;
274 }
275 }
276 // Call the finalize() method of all Output streams
277 for ( ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
278 sc = (*ita)->sysFinalize();
279 if( !sc.isSuccess() ) {
280 scRet = StatusCode::FAILURE;
281 warning() << "Finalization of algorithm " << (*ita)->name() << " failed" << endmsg;
282 }
283 }
284 // release all top algorithms
285 SmartIF<IAlgManager> algMan(serviceLocator());
286 for ( ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
287 if (algMan->removeAlgorithm(*ita).isFailure()) {
288 scRet = StatusCode::FAILURE;
289 warning() << "Problems removing Algorithm " << (*ita)->name() << endmsg;
290 }
291 }
292 m_topAlgList.clear();
293
294 // release all output streams
295 for ( ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
296 (*ita)->release();
297 }
298 m_outStreamList.clear();
299 if ( sc.isSuccess() ) m_state = FINALIZED;
300
301 m_incidentSvc->removeListener(m_abortEventListener, IncidentType::AbortEvent);
302 m_abortEventListener = 0; // release
303
304 m_incidentSvc = 0; // release
305 m_appMgrUI = 0; // release
306
307 sc = Service::finalize();
308
309 if (sc.isFailure()) {
310 scRet = StatusCode::FAILURE;
311 error() << "Problems finalizing Service base class" << endmsg;
312 }
313
314 return scRet;
315 }
316
317 //--------------------------------------------------------------------------------------------
318 // implementation of IAppMgrUI::nextEvent
319 //--------------------------------------------------------------------------------------------
320 StatusCode MinimalEventLoopMgr::nextEvent(int /* maxevt */) {
321 error() << "This method cannot be called on an object of type "
322 << System::typeinfoName(typeid(*this)) << endmsg;
323 return StatusCode::FAILURE;
324 }
325
326 //--------------------------------------------------------------------------------------------
327 // IEventProcessing::executeRun
328 //--------------------------------------------------------------------------------------------
329 StatusCode MinimalEventLoopMgr::executeRun( int maxevt ) {
330 StatusCode sc;
331 ListAlg::iterator ita;
332 bool eventfailed = false;
333
334 // Call the beginRun() method of all top algorithms
335 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
336 sc = (*ita)->sysBeginRun();
337 if (!sc.isSuccess()) {
338 warning() << "beginRun() of algorithm " << (*ita)->name() << " failed" << endmsg;
339 eventfailed = true;
340 }
341 }
342
343 // Call now the nextEvent(...)
344 sc = nextEvent(maxevt);
345 if (!sc.isSuccess()) {
346 eventfailed = true;
347 }
348
349 // Call the endRun() method of all top algorithms
350 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
351 sc = (*ita)->sysEndRun();
352 if (!sc.isSuccess()) {
353 warning() << "endRun() of algorithm " << (*ita)->name() << " failed" << endmsg;
354 eventfailed = true;
355 }
356 }
357
358 if (eventfailed) {
359 return StatusCode::FAILURE;
360 }
361 else {
362 return StatusCode::SUCCESS;
363 }
364 }
365
366 namespace {
369 class RetCodeGuard {
370 public:
371 inline RetCodeGuard(const SmartIF<IProperty> &appmgr, int retcode):
372 m_appmgr(appmgr), m_retcode(retcode) {}
373 inline void ignore() {
374 m_retcode = Gaudi::ReturnCode::Success;
375 }
376 inline ~RetCodeGuard() {
377 if (UNLIKELY(Gaudi::ReturnCode::Success != m_retcode)) {
378 Gaudi::setAppReturnCode(m_appmgr, m_retcode);
379 }
380 }
381 private:
382 SmartIF<IProperty> m_appmgr;
383 int m_retcode;
384 };
385 }
386 //--------------------------------------------------------------------------------------------
387 // Implementation of IEventProcessor::executeEvent(void* par)
388 //--------------------------------------------------------------------------------------------
389 StatusCode MinimalEventLoopMgr::executeEvent(void* /* par */) {
390 bool eventfailed = false;
391
392 // Call the resetExecuted() method of ALL "known" algorithms
393 // (before we were reseting only the topalgs)
394 SmartIF<IAlgManager> algMan(serviceLocator());
395 if (LIKELY(algMan.isValid())) {
396 const ListAlgPtrs& allAlgs = algMan->getAlgorithms() ;
397 for( ListAlgPtrs::const_iterator ialg = allAlgs.begin() ; allAlgs.end() != ialg ; ++ialg ) {
398 if (LIKELY(0 != *ialg)) (*ialg)->resetExecuted();
399 }
400 }
401
402 // Get the IProperty interface of the ApplicationMgr to pass it to RetCodeGuard
403 const SmartIF<IProperty> appmgr(serviceLocator());
404 // Call the execute() method of all top algorithms
405 for (ListAlg::iterator ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
406 StatusCode sc(StatusCode::FAILURE);
407 try {
408 if (UNLIKELY(m_abortEvent)) {
409 DEBMSG << "AbortEvent incident fired by "
410 << m_abortEventSource << endmsg;
411 m_abortEvent = false;
412 sc.ignore();
413 break;
414 }
415 RetCodeGuard rcg(appmgr, Gaudi::ReturnCode::UnhandledException);
416 sc = (*ita)->sysExecute();
417 rcg.ignore(); // disarm the guard
418 } catch ( const GaudiException& Exception ) {
419 fatal() << ".executeEvent(): Exception with tag=" << Exception.tag()
420 << " thrown by " << (*ita)->name() << endmsg;
421 error() << Exception << endmsg;
422 } catch ( const std::exception& Exception ) {
423 fatal() << ".executeEvent(): Standard std::exception thrown by "
424 << (*ita)->name() << endmsg;
425 error() << Exception.what() << endmsg;
426 } catch(...) {
427 fatal() << ".executeEvent(): UNKNOWN Exception thrown by "
428 << (*ita)->name() << endmsg;
429 }
430
431 if (UNLIKELY(!sc.isSuccess())) {
432 warning() << "Execution of algorithm " << (*ita)->name() << " failed" << endmsg;
433 eventfailed = true;
434 }
435 }
436
437 // ensure that the abortEvent flag is cleared before the next event
438 if (UNLIKELY(m_abortEvent)) {
439 DEBMSG << "AbortEvent incident fired by " << m_abortEventSource << endmsg;
440 m_abortEvent = false;
441 }
442
443 // Call the execute() method of all output streams
444 for (ListAlg::iterator ito = m_outStreamList.begin(); ito != m_outStreamList.end(); ito++ ) {
445 (*ito)->resetExecuted();
446 StatusCode sc;
447 sc = (*ito)->sysExecute();
448 if (UNLIKELY(!sc.isSuccess())) {
449 warning() << "Execution of output stream " << (*ito)->name() << " failed" << endmsg;
450 eventfailed = true;
451 }
452 }
453
454 // Check if there was an error processing current event
455 if (UNLIKELY(eventfailed)){
456 error() << "Error processing event loop." << endmsg;
457 return StatusCode(StatusCode::FAILURE,true);
458 }
459 return StatusCode(StatusCode::SUCCESS,true);
460 }
461 //--------------------------------------------------------------------------------------------
462 // Implementation of IEventProcessor::stopRun()
463 //--------------------------------------------------------------------------------------------
464 StatusCode MinimalEventLoopMgr::stopRun() {
465 // Set the application return code
466 SmartIF<IProperty> appmgr(serviceLocator());
467 if(Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::ScheduledStop).isFailure()) {
468 error() << "Could not set return code of the application ("
469 << Gaudi::ReturnCode::ScheduledStop << ")" << endmsg;
470 }
471 m_scheduledStop = true;
472 return StatusCode::SUCCESS;
473 }
474
475 //--------------------------------------------------------------------------------------------
476 // Top algorithm List handler
477 //--------------------------------------------------------------------------------------------
478 void MinimalEventLoopMgr::topAlgHandler( Property& /* theProp */ ) {
479 if ( !(decodeTopAlgs( )).isSuccess() ) {
480 throw GaudiException("Failed to initialize Top Algorithms streams.",
481 "MinimalEventLoopMgr::topAlgHandler",
482 StatusCode::FAILURE);
483 }
484 }
485
486 //--------------------------------------------------------------------------------------------
487 // decodeTopAlgNameList & topAlgNameListHandler
488 //--------------------------------------------------------------------------------------------
489 StatusCode MinimalEventLoopMgr::decodeTopAlgs() {
490 StatusCode sc = StatusCode::SUCCESS;
491 if ( CONFIGURED == m_state || INITIALIZED == m_state ) {
492 SmartIF<IAlgManager> algMan(serviceLocator());
493 if ( algMan.isValid()) {
494 // Reset the existing Top Algorithm List
495 m_topAlgList.clear( );
496 const std::vector<std::string>& algNames = m_topAlgNames.value( );
497 for (VectorName::const_iterator it = algNames.begin(); it != algNames.end(); it++) {
498 Gaudi::Utils::TypeNameString item(*it);
499 // Got the type and name. Now creating the algorithm, avoiding duplicate creation.
500 std::string item_name = item.name() + getGaudiThreadIDfromName(name());
501 const bool CREATE = false;
502 SmartIF<IAlgorithm> alg = algMan->algorithm(item_name, CREATE);
503 if (alg.isValid()) {
504 DEBMSG << "Top Algorithm " << item_name << " already exists" << endmsg;
505 }
506 else {
507 DEBMSG << "Creating Top Algorithm " << item.type() << " with name " << item_name << endmsg;
508 IAlgorithm *ialg = 0;
509 StatusCode sc1 = algMan->createAlgorithm(item.type(), item_name, ialg);
510 if( !sc1.isSuccess() ) {
511 error() << "Unable to create Top Algorithm " << item.type() << " with name " << item_name << endmsg;
512 return sc1;
513 }
514 alg = ialg; // manage reference counting
515 }
516 m_topAlgList.push_back(alg);
517 }
518 return sc;
519 }
520 sc = StatusCode::FAILURE;
521 }
522 return sc;
523 }
524
525 //--------------------------------------------------------------------------------------------
526 // Output stream List handler
527 //--------------------------------------------------------------------------------------------
528 void MinimalEventLoopMgr::outStreamHandler( Property& /* theProp */ ) {
529 if ( !(decodeOutStreams( )).isSuccess() ) {
530 throw GaudiException("Failed to initialize output streams.",
531 "MinimalEventLoopMgr::outStreamHandler",
532 StatusCode::FAILURE);
533 }
534 }
535
536 //--------------------------------------------------------------------------------------------
537 // decodeOutStreamNameList & outStreamNameListHandler
538 //--------------------------------------------------------------------------------------------
539 StatusCode MinimalEventLoopMgr::decodeOutStreams( ) {
540 StatusCode sc = StatusCode::SUCCESS;
541 if ( CONFIGURED == m_state || INITIALIZED == m_state ) {
542 SmartIF<IAlgManager> algMan(serviceLocator());
543 if ( algMan.isValid() ) {
544 // Reset the existing Top Algorithm List
545 m_outStreamList.clear();
546 const std::vector<std::string>& algNames = m_outStreamNames.value( );
547 for (VectorName::const_iterator it = algNames.begin(); it != algNames.end(); it++) {
548 Gaudi::Utils::TypeNameString item(*it, m_outStreamType);
549 DEBMSG << "Creating " << m_outStreamType << (*it) << endmsg;
550 const bool CREATE = false;
551 SmartIF<IAlgorithm> os = algMan->algorithm( item, CREATE );
552 if (os.isValid()) {
553 DEBMSG << "Output Stream " << item.name() << " already exists" << endmsg;
554 }
555 else {
556 DEBMSG << "Creating Output Stream " << (*it) << endmsg;
557 IAlgorithm* ios = 0;
558 StatusCode sc1 = algMan->createAlgorithm( item.type(), item.name(), ios );
559 if( !sc1.isSuccess() ) {
560 error() << "Unable to create Output Stream " << (*it) << endmsg;
561 return sc1;
562 }
563 os = ios; // manage reference counting
564 }
565 m_outStreamList.push_back( os );
566 }
567 return sc;
568 }
569 sc = StatusCode::FAILURE;
570 }
571 return sc;
572 }
573
574