00001
00002 #define GAUDIKERNEL_MINIMALEVENTLOOPMGR_CPP
00003
00004 #include "GaudiKernel/SmartIF.h"
00005 #include "GaudiKernel/MsgStream.h"
00006 #include "GaudiKernel/IAlgorithm.h"
00007 #include "GaudiKernel/IAlgManager.h"
00008 #include "GaudiKernel/TypeNameString.h"
00009 #include "GaudiKernel/GaudiException.h"
00010 #include "GaudiKernel/ThreadGaudi.h"
00011 #include "GaudiKernel/Incident.h"
00012 #include "GaudiKernel/IIncidentListener.h"
00013 #include "GaudiKernel/IIncidentSvc.h"
00014 #include "GaudiKernel/AppReturnCode.h"
00015
00016 #include "GaudiKernel/MinimalEventLoopMgr.h"
00017
00018 namespace {
00019 class AbortEventListener: public implements1<IIncidentListener> {
00020 public:
00021 AbortEventListener(bool &flag, std::string &source):m_flag(flag),
00022 m_source(source){
00023 addRef();
00024 }
00025 virtual ~AbortEventListener() {}
00027 virtual void handle(const Incident& i) {
00028 if (i.type() == IncidentType::AbortEvent) {
00029 m_flag = true;
00030 m_source = i.source();
00031 }
00032 }
00033
00034 private:
00036 bool &m_flag;
00038 std::string &m_source;
00039 };
00040 }
00041
00042
00043
00044
00045 MinimalEventLoopMgr::MinimalEventLoopMgr(const std::string& nam, ISvcLocator* svcLoc)
00046 : base_class(nam, svcLoc), m_appMgrUI(svcLoc)
00047 {
00048 declareProperty("TopAlg", m_topAlgNames );
00049 declareProperty("OutStream", m_outStreamNames );
00050 declareProperty("OutStreamType", m_outStreamType = "OutputStream");
00051 m_topAlgNames.declareUpdateHandler ( &MinimalEventLoopMgr::topAlgHandler, this );
00052 m_outStreamNames.declareUpdateHandler( &MinimalEventLoopMgr::outStreamHandler, this );
00053 m_state = OFFLINE;
00054 m_scheduledStop = false;
00055 m_abortEvent = false;
00056 }
00057
00058
00059
00060
00061 MinimalEventLoopMgr::~MinimalEventLoopMgr() {
00062 m_state = OFFLINE;
00063 }
00064
00065
00066
00067
00068 StatusCode MinimalEventLoopMgr::initialize() {
00069
00070 MsgStream log(msgSvc(), name());
00071
00072 if ( !m_appMgrUI.isValid() ) {
00073 return StatusCode::FAILURE;
00074 }
00075
00076 StatusCode sc = Service::initialize();
00077 if ( !sc.isSuccess() ) {
00078 log << MSG::ERROR << "Failed to initialize Service Base class." << endmsg;
00079 return StatusCode::FAILURE;
00080 }
00081
00082 SmartIF<IProperty> prpMgr(serviceLocator());
00083 if ( ! prpMgr.isValid() ) {
00084 log << MSG::ERROR << "Error retrieving AppMgr interface IProperty." << endmsg;
00085 return StatusCode::FAILURE;
00086 }
00087 else {
00088 if ( m_topAlgNames.value().size() == 0 ) {
00089 setProperty(prpMgr->getProperty("TopAlg")).ignore();
00090 }
00091 if ( m_outStreamNames.value().size() == 0 ) {
00092 setProperty(prpMgr->getProperty("OutStream")).ignore();
00093 }
00094 }
00095
00096
00097 m_incidentSvc = serviceLocator()->service("IncidentSvc");
00098 if( !m_incidentSvc.isValid() ) {
00099 log << MSG::FATAL << "Error retrieving IncidentSvc." << endmsg;
00100 return StatusCode::FAILURE;
00101 }
00102
00103 m_abortEventListener = new AbortEventListener(m_abortEvent,m_abortEventSource);
00104 m_incidentSvc->addListener(m_abortEventListener,IncidentType::AbortEvent);
00105
00106
00107 m_state = INITIALIZED;
00108
00109
00110
00111
00112
00113
00114 sc = decodeOutStreams();
00115 if ( !sc.isSuccess() ) {
00116 log << MSG::ERROR << "Failed to initialize Output streams." << endmsg;
00117 m_state = CONFIGURED;
00118 return sc;
00119 }
00120
00121
00122
00123
00124
00125 sc = decodeTopAlgs();
00126 if ( !sc.isSuccess() ) {
00127 log << MSG::ERROR << "Failed to initialize Top Algorithms streams." << endmsg;
00128 m_state = CONFIGURED;
00129 return sc;
00130 }
00131
00132 ListAlg::iterator ita;
00133
00134
00135 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00136 sc = (*ita)->sysInitialize();
00137 if( !sc.isSuccess() ) {
00138 log << MSG::ERROR << "Unable to initialize Algorithm: " << (*ita)->name() << endmsg;
00139 return sc;
00140 }
00141 }
00142 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
00143 sc = (*ita)->sysInitialize();
00144 if( !sc.isSuccess() ) {
00145 log << MSG::ERROR << "Unable to initialize Output Stream: " << (*ita)->name() << endmsg;
00146 return sc;
00147 }
00148 }
00149
00150 return StatusCode::SUCCESS;
00151 }
00152
00153
00154
00155 StatusCode MinimalEventLoopMgr::start() {
00156
00157 StatusCode sc = Service::start();
00158 if ( ! sc.isSuccess() ) return sc;
00159
00160 MsgStream log(msgSvc(), name());
00161
00162 ListAlg::iterator ita;
00163
00164
00165 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00166 sc = (*ita)->sysStart();
00167 if( !sc.isSuccess() ) {
00168 log << MSG::ERROR << "Unable to start Algorithm: " << (*ita)->name() << endmsg;
00169 return sc;
00170 }
00171 }
00172 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
00173 sc = (*ita)->sysStart();
00174 if( !sc.isSuccess() ) {
00175 log << MSG::ERROR << "Unable to start Output Stream: " << (*ita)->name() << endmsg;
00176 return sc;
00177 }
00178 }
00179 return StatusCode::SUCCESS;
00180 }
00181
00182
00183
00184 StatusCode MinimalEventLoopMgr::stop() {
00185
00186 StatusCode sc = StatusCode::SUCCESS;
00187
00188 MsgStream log(msgSvc(), name());
00189
00190 ListAlg::iterator ita;
00191
00192
00193 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00194 sc = (*ita)->sysStop();
00195 if( !sc.isSuccess() ) {
00196 log << MSG::ERROR << "Unable to stop Algorithm: " << (*ita)->name() << endmsg;
00197 return sc;
00198 }
00199 }
00200 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
00201 sc = (*ita)->sysStop();
00202 if( !sc.isSuccess() ) {
00203 log << MSG::ERROR << "Unable to stop Output Stream: " << (*ita)->name() << endmsg;
00204 return sc;
00205 }
00206 }
00207
00208 return Service::stop();
00209 }
00210
00211
00212
00213
00214 StatusCode MinimalEventLoopMgr::reinitialize() {
00215 MsgStream log( msgSvc(), name() );
00216 StatusCode sc = StatusCode::SUCCESS;
00217 ListAlg::iterator ita;
00218
00219
00220 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00221 sc = (*ita)->sysReinitialize();
00222 if( !sc.isSuccess() ) {
00223 log << MSG::ERROR << "Unable to reinitialize Algorithm: " << (*ita)->name() << endmsg;
00224 return sc;
00225 }
00226 }
00227 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
00228 sc = (*ita)->sysReinitialize();
00229 if( !sc.isSuccess() ) {
00230 log << MSG::ERROR << "Unable to reinitialize Output Stream: " << (*ita)->name() << endmsg;
00231 return sc;
00232 }
00233 }
00234
00235 return sc;
00236 }
00237
00238
00239
00240 StatusCode MinimalEventLoopMgr::restart() {
00241 MsgStream log( msgSvc(), name() );
00242 StatusCode sc = StatusCode::SUCCESS;
00243 ListAlg::iterator ita;
00244
00245
00246 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00247 sc = (*ita)->sysRestart();
00248 if( !sc.isSuccess() ) {
00249 log << MSG::ERROR << "Unable to restart Algorithm: " << (*ita)->name() << endmsg;
00250 return sc;
00251 }
00252 }
00253 for (ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
00254 sc = (*ita)->sysRestart();
00255 if( !sc.isSuccess() ) {
00256 log << MSG::ERROR << "Unable to restart Output Stream: " << (*ita)->name() << endmsg;
00257 return sc;
00258 }
00259 }
00260
00261 return sc;
00262 }
00263
00264
00265
00266
00267 StatusCode MinimalEventLoopMgr::finalize() {
00268 MsgStream log( msgSvc(), name() );
00269 StatusCode sc = StatusCode::SUCCESS;
00270 StatusCode scRet = StatusCode::SUCCESS;
00271
00272 ListAlg::iterator ita;
00273 for ( ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00274 sc = (*ita)->sysFinalize();
00275 if( !sc.isSuccess() ) {
00276 scRet = StatusCode::FAILURE;
00277 log << MSG::WARNING << "Finalization of algorithm " << (*ita)->name() << " failed" << endmsg;
00278 }
00279 }
00280
00281 for ( ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
00282 sc = (*ita)->sysFinalize();
00283 if( !sc.isSuccess() ) {
00284 scRet = StatusCode::FAILURE;
00285 log << MSG::WARNING << "Finalization of algorithm " << (*ita)->name() << " failed" << endmsg;
00286 }
00287 }
00288
00289 SmartIF<IAlgManager> algMan(serviceLocator());
00290 for ( ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00291 if (algMan->removeAlgorithm(*ita).isFailure()) {
00292 scRet = StatusCode::FAILURE;
00293 log << MSG::ERROR << "Problems removing Algorithm " << (*ita)->name()
00294 << endmsg;
00295 }
00296 }
00297 m_topAlgList.clear();
00298
00299
00300 for ( ita = m_outStreamList.begin(); ita != m_outStreamList.end(); ita++ ) {
00301 (*ita)->release();
00302 }
00303 m_outStreamList.clear();
00304 if ( sc.isSuccess() ) m_state = FINALIZED;
00305
00306 m_incidentSvc->removeListener(m_abortEventListener, IncidentType::AbortEvent);
00307 m_abortEventListener = 0;
00308
00309 m_incidentSvc = 0;
00310 m_appMgrUI = 0;
00311
00312 sc = Service::finalize();
00313
00314 if (sc.isFailure()) {
00315 scRet = StatusCode::FAILURE;
00316 log << MSG::ERROR << "Problems finalizing Service base class" << endmsg;
00317 }
00318
00319 return scRet;
00320 }
00321
00322
00323
00324
00325 StatusCode MinimalEventLoopMgr::nextEvent(int ) {
00326 MsgStream log(msgSvc(), name());
00327 log << MSG::ERROR << "This method cannot be called on an object of type "
00328 << System::typeinfoName(typeid(*this)) << endmsg;
00329 return StatusCode::FAILURE;
00330 }
00331
00332
00333
00334
00335 StatusCode MinimalEventLoopMgr::executeRun( int maxevt ) {
00336 StatusCode sc;
00337 MsgStream log( msgSvc(), name() );
00338 ListAlg::iterator ita;
00339 bool eventfailed = false;
00340
00341
00342 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00343 sc = (*ita)->sysBeginRun();
00344 if( !sc.isSuccess() ) {
00345 log << MSG::WARNING << "beginRun() of algorithm " << (*ita)->name() << " failed" << endmsg;
00346 eventfailed = true;
00347 }
00348 }
00349
00350
00351 sc = nextEvent(maxevt);
00352 if( !sc.isSuccess() ) {
00353 eventfailed = true;
00354 }
00355
00356
00357 for (ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00358 sc = (*ita)->sysEndRun();
00359 if( !sc.isSuccess() ) {
00360 log << MSG::WARNING << "endRun() of algorithm " << (*ita)->name() << " failed" << endmsg;
00361 eventfailed = true;
00362 }
00363 }
00364
00365 if( eventfailed ){
00366 return StatusCode::FAILURE;
00367 }
00368 else {
00369 return StatusCode::SUCCESS;
00370 }
00371 }
00372
00373 namespace {
00376 class RetCodeGuard {
00377 public:
00378 inline RetCodeGuard(const SmartIF<IProperty> &appmgr, int retcode):
00379 m_appmgr(appmgr), m_retcode(retcode) {}
00380 inline void ignore() {
00381 m_retcode = Gaudi::ReturnCode::Success;
00382 }
00383 inline ~RetCodeGuard() {
00384 if (Gaudi::ReturnCode::Success != m_retcode) {
00385 Gaudi::setAppReturnCode(m_appmgr, m_retcode);
00386 }
00387 }
00388 private:
00389 SmartIF<IProperty> m_appmgr;
00390 int m_retcode;
00391 };
00392 }
00393
00394
00395
00396 StatusCode MinimalEventLoopMgr::executeEvent(void* ) {
00397 bool eventfailed = false;
00398
00399
00400
00401 SmartIF<IAlgManager> algMan(serviceLocator());
00402 if ( algMan.isValid() ) {
00403 const ListAlgPtrs& allAlgs = algMan->getAlgorithms() ;
00404 for( ListAlgPtrs::const_iterator ialg = allAlgs.begin() ; allAlgs.end() != ialg ; ++ialg ) {
00405 if ( 0 != *ialg ) (*ialg)->resetExecuted();
00406 }
00407 }
00408
00409
00410 const SmartIF<IProperty> appmgr(serviceLocator());
00411
00412 for (ListAlg::iterator ita = m_topAlgList.begin(); ita != m_topAlgList.end(); ita++ ) {
00413 StatusCode sc(StatusCode::FAILURE);
00414 try {
00415 if (m_abortEvent){
00416 MsgStream log ( msgSvc() , name() );
00417 log << MSG::DEBUG << "AbortEvent incident fired by "
00418 << m_abortEventSource << endmsg;
00419 m_abortEvent = false;
00420 sc.ignore();
00421 break;
00422 }
00423 RetCodeGuard rcg(appmgr, Gaudi::ReturnCode::UnhandledException);
00424 sc = (*ita)->sysExecute();
00425 rcg.ignore();
00426 } catch ( const GaudiException& Exception ) {
00427 MsgStream log ( msgSvc() , "MinimalEventLoopMgr.executeEvent()" );
00428 log << MSG::FATAL << " Exception with tag=" << Exception.tag()
00429 << " thrown by " << (*ita)->name() << endmsg;
00430 log << MSG::ERROR << Exception << endmsg;
00431 } catch ( const std::exception& Exception ) {
00432 MsgStream log ( msgSvc() , "MinimalEventLoopMgr.executeEvent()" );
00433 log << MSG::FATAL << " Standard std::exception thrown by "
00434 << (*ita)->name() << endmsg;
00435 log << MSG::ERROR << Exception.what() << endmsg;
00436 } catch(...) {
00437 MsgStream log ( msgSvc() , "MinimalEventLoopMgr.executeEvent()" );
00438 log << MSG::FATAL << "UNKNOWN Exception thrown by "
00439 << (*ita)->name() << endmsg;
00440 }
00441
00442 if( !sc.isSuccess() ) {
00443 MsgStream log( msgSvc(), name() );
00444 log << MSG::WARNING << "Execution of algorithm " << (*ita)->name() << " failed" << endmsg;
00445 eventfailed = true;
00446 }
00447 }
00448
00449
00450 if (m_abortEvent){
00451 if (outputLevel() <= MSG::DEBUG) {
00452 MsgStream log ( msgSvc() , name() );
00453 log << MSG::DEBUG << "AbortEvent incident fired by "
00454 << m_abortEventSource << endmsg;
00455 }
00456 m_abortEvent = false;
00457 }
00458
00459
00460 for (ListAlg::iterator ito = m_outStreamList.begin(); ito != m_outStreamList.end(); ito++ ) {
00461 (*ito)->resetExecuted();
00462 StatusCode sc;
00463 sc = (*ito)->sysExecute();
00464 if( !sc.isSuccess() ) {
00465 MsgStream log( msgSvc(), name() );
00466 log << MSG::WARNING << "Execution of output stream " << (*ito)->name() << " failed" << endmsg;
00467 eventfailed = true;
00468 }
00469 }
00470
00471
00472 if( eventfailed ){
00473 MsgStream log( msgSvc(), name() );
00474 log << MSG::ERROR << "Error processing event loop." << endmsg;
00475 return StatusCode(StatusCode::FAILURE,true);
00476 }
00477 return StatusCode(StatusCode::SUCCESS,true);
00478 }
00479
00480
00481
00482 StatusCode MinimalEventLoopMgr::stopRun() {
00483
00484 SmartIF<IProperty> appmgr(serviceLocator());
00485 if(Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::ScheduledStop).isFailure()) {
00486 MsgStream( msgSvc(), name() )
00487 << MSG::ERROR << "Could not set return code of the application ("
00488 << Gaudi::ReturnCode::ScheduledStop << ")" << endmsg;
00489 }
00490 m_scheduledStop = true;
00491 return StatusCode::SUCCESS;
00492 }
00493
00494
00495
00496
00497 void MinimalEventLoopMgr::topAlgHandler( Property& ) {
00498 if ( !(decodeTopAlgs( )).isSuccess() ) {
00499 throw GaudiException("Failed to initialize Top Algorithms streams.",
00500 "MinimalEventLoopMgr::topAlgHandler",
00501 StatusCode::FAILURE);
00502 }
00503 }
00504
00505
00506
00507
00508 StatusCode MinimalEventLoopMgr::decodeTopAlgs() {
00509 StatusCode sc = StatusCode::SUCCESS;
00510 if ( CONFIGURED == m_state || INITIALIZED == m_state ) {
00511 SmartIF<IAlgManager> algMan(serviceLocator());
00512 MsgStream log(msgSvc(), name());
00513 if ( algMan.isValid()) {
00514
00515 m_topAlgList.clear( );
00516 const std::vector<std::string>& algNames = m_topAlgNames.value( );
00517 for (VectorName::const_iterator it = algNames.begin(); it != algNames.end(); it++) {
00518 Gaudi::Utils::TypeNameString item(*it);
00519
00520 std::string item_name = item.name() + getGaudiThreadIDfromName(name());
00521 const bool CREATE = false;
00522 SmartIF<IAlgorithm> alg = algMan->algorithm(item_name, CREATE);
00523 if (alg.isValid()) {
00524 log << MSG::DEBUG << "Top Algorithm " << item_name << " already exists" << endmsg;
00525 }
00526 else {
00527 log << MSG::DEBUG << "Creating Top Algorithm " << item.type() << " with name " << item_name << endmsg;
00528 IAlgorithm *ialg = 0;
00529 StatusCode sc1 = algMan->createAlgorithm(item.type(), item_name, ialg);
00530 if( !sc1.isSuccess() ) {
00531 log << MSG::ERROR << "Unable to create Top Algorithm " << item.type() << " with name " << item_name << endmsg;
00532 return sc1;
00533 }
00534 alg = ialg;
00535 }
00536 m_topAlgList.push_back(alg);
00537 }
00538 return sc;
00539 }
00540 sc = StatusCode::FAILURE;
00541 }
00542 return sc;
00543 }
00544
00545
00546
00547
00548 void MinimalEventLoopMgr::outStreamHandler( Property& ) {
00549 if ( !(decodeOutStreams( )).isSuccess() ) {
00550 throw GaudiException("Failed to initialize output streams.",
00551 "MinimalEventLoopMgr::outStreamHandler",
00552 StatusCode::FAILURE);
00553 }
00554 }
00555
00556
00557
00558
00559 StatusCode MinimalEventLoopMgr::decodeOutStreams( ) {
00560 StatusCode sc = StatusCode::SUCCESS;
00561 if ( CONFIGURED == m_state || INITIALIZED == m_state ) {
00562 MsgStream log(msgSvc(), name());
00563 SmartIF<IAlgManager> algMan(serviceLocator());
00564 if ( algMan.isValid() ) {
00565
00566 m_outStreamList.clear();
00567 const std::vector<std::string>& algNames = m_outStreamNames.value( );
00568 for (VectorName::const_iterator it = algNames.begin(); it != algNames.end(); it++) {
00569 Gaudi::Utils::TypeNameString item(*it, m_outStreamType);
00570 log << MSG::DEBUG << "Creating " << m_outStreamType << (*it) << endmsg;
00571 const bool CREATE = false;
00572 SmartIF<IAlgorithm> os = algMan->algorithm( item, CREATE );
00573 if (os.isValid()) {
00574 log << MSG::DEBUG << "Output Stream " << item.name() << " already exists" << endmsg;
00575 }
00576 else {
00577 log << MSG::DEBUG << "Creating Output Stream " << (*it) << endmsg;
00578 IAlgorithm* ios = 0;
00579 StatusCode sc1 = algMan->createAlgorithm( item.type(), item.name(), ios );
00580 if( !sc1.isSuccess() ) {
00581 log << MSG::ERROR << "Unable to create Output Stream " << (*it) << endmsg;
00582 return sc1;
00583 }
00584 os = ios;
00585 }
00586 m_outStreamList.push_back( os );
00587 }
00588 return sc;
00589 }
00590 sc = StatusCode::FAILURE;
00591 }
00592 return sc;
00593 }
00594
00595