/search.css" rel="stylesheet" type="text/css"/> /search.js">
00001 #include "DybDualEventLoopMgr.h" 00002 00003 #include "DybKernel/HybridExecutionIncident.h" 00004 #include "DybKernel/IAesFeeder.h" 00005 00006 #include "GaudiKernel/ListItem.h" 00007 #include "GaudiKernel/IIncidentSvc.h" 00008 #include "GaudiKernel/IAlgorithm.h" 00009 #include "GaudiKernel/IAlgManager.h" 00010 #include "GaudiKernel/ThreadGaudi.h" 00011 #include "GaudiKernel/IDataManagerSvc.h" 00012 #include "GaudiKernel/IDataProviderSvc.h" 00013 #include "GaudiKernel/IDataStoreAgent.h" 00014 #include "GaudiKernel/IRegistry.h" 00015 #include "GaudiKernel/DataObject.h" 00016 00017 #include <vector> 00018 #include <string> 00019 00020 typedef std::list<IAlgorithm*> ListAlg; 00021 00022 00023 class ELMState { 00024 public: 00025 ListAlg topAlgList; 00026 int total_nevt; 00027 00028 ELMState() 00029 : topAlgList() 00030 , total_nevt(0) 00031 { } 00032 }; 00033 00034 #include "DybDualELM_HEIHandler.h" 00035 00036 00037 DybDualEventLoopMgr::DybDualEventLoopMgr(const std::string& nam, ISvcLocator* svcLoc) 00038 : DybEventLoopMgr(nam, svcLoc) 00039 , m_theState(0) 00040 , m_state1(new ELMState) 00041 , m_state2(new ELMState) 00042 , m_incsvc(0) 00043 , m_heiHandler(0) 00044 { 00045 // My additional properties 00046 declareProperty("EventBuilderAlg",m_eventBuilderAlgName = "EventBuilderAlg", 00047 "Name of the algorithm responsible for building events (def: EventBuilderAlg)"); 00048 } 00049 00050 DybDualEventLoopMgr::~DybDualEventLoopMgr() 00051 { 00052 } 00053 00054 StatusCode DybDualEventLoopMgr::initialize() 00055 { 00056 MsgStream log(msgSvc(), name()); 00057 00058 log << MSG::DEBUG 00059 << "calling DybEventLoopMgr::intialize()," 00060 << " state = " << FSMState() 00061 << " targeting " << targetFSMState() 00062 << endreq; 00063 00064 StatusCode sc = DybEventLoopMgr::initialize(); 00065 if (sc.isFailure()) { 00066 log << MSG::ERROR << "Failed to initialize DybEventLoopMgr base class" << endreq; 00067 return sc; 00068 } 00069 log << MSG::DEBUG 00070 << "returned from DybEventLoopMgr::intialize()" 00071 << " state = " << FSMState() 00072 << " targeting " << targetFSMState() 00073 << endreq; 00074 00075 00076 sc = m_evtDataSvc->queryInterface(IAesFeeder::interfaceID(),(void**)&m_aesfeed); 00077 if (sc.isFailure()) { 00078 log << MSG::ERROR 00079 << "Failed to get interface IAesFeeder from event data service." 00080 << endreq; 00081 return sc; 00082 } 00083 00084 sc = this->initialize_algs(); 00085 if (sc.isFailure()) { 00086 log << MSG::ERROR << "Failed to initialize algorithms" << endreq; 00087 return sc; 00088 } 00089 00090 // Connect to "HybridExecutionIncident" 00091 sc = this->service("IncidentSvc",m_incsvc,true); 00092 if (sc.isFailure()) { 00093 log << MSG::ERROR 00094 << "Failed to get IncidentSvc" << endreq; 00095 return sc; 00096 } 00097 00098 m_heiHandler = new HEIHandler(m_theState, m_state1, m_state2); 00099 m_incsvc->addListener(m_heiHandler,"HybridExecutionIncident"); 00100 00101 return StatusCode::SUCCESS; 00102 } 00103 00104 00105 StatusCode DybDualEventLoopMgr::initialize_algs() 00106 { 00107 MsgStream log(msgSvc(), name()); 00108 StatusCode sc = StatusCode::SUCCESS; 00109 00110 log << MSG::DEBUG 00111 << "initializing top alg lists with " 00112 << m_topAlgList.size() 00113 << " algorithms." 00114 << endreq; 00115 00116 ELMState* theState = m_state1; 00117 ListAlg::iterator it, done = m_topAlgList.end(); 00118 for (it = m_topAlgList.begin(); it != done; ++it) { 00119 IAlgorithm* ialg = *it; 00120 SmartIF<IStateful> istate(IID_IStateful,ialg); 00121 00122 std::string name = ialg->name(); 00123 00124 log << MSG::DEBUG 00125 << "Algorithm \"" << name << "\"" 00126 << " in state " << istate->FSMState() 00127 << " targetting " << istate->targetFSMState() 00128 << endreq; 00129 00130 theState->topAlgList.push_back(ialg); 00131 if (name == m_eventBuilderAlgName) { 00132 theState = m_state2; // switch to second list 00133 theState->topAlgList.push_back(ialg); // event builder goes in both 00134 } 00135 } 00136 00137 if (!m_state2->topAlgList.size()) { 00138 log << MSG::WARNING 00139 << "Did not find event builder algorithm: \"" 00140 << m_eventBuilderAlgName << "\"" 00141 << endreq; 00142 //return StatusCode::FAILURE; 00143 } 00144 00145 // Start with list #1 00146 m_theState = m_state1; 00147 switch_state(true); 00148 return sc; 00149 } 00150 00151 static void dump_algs(MsgStream& log, ListAlg& algs) 00152 { 00153 ListAlg::iterator it, done = algs.end(); 00154 for (it = algs.begin(); it != done; ++it) { 00155 log << MSG::DEBUG 00156 << "\t" << (*it)->name() 00157 << endreq; 00158 } 00159 } 00160 00161 bool DybDualEventLoopMgr::switch_state(bool force) 00162 { 00163 MsgStream log(msgSvc(), name()); 00164 00165 if (!force && m_theLastState == m_theState) { 00166 log << MSG::DEBUG 00167 << "switch_state("<<force<<") keeping state " 00168 << (m_theState == m_state1 ? "one" : "two") 00169 << endreq; 00170 return false; 00171 } 00172 00173 // Set MinimalEventLoopMgr's TopAlg list 00174 m_theLastState = m_theState; 00175 m_topAlgList = m_theState->topAlgList; 00176 00177 log << MSG::DEBUG 00178 << "switch_state("<<force<<") switched state to " 00179 << (m_theState == m_state1 ? "one" : "two") 00180 << " with algs:" 00181 << endreq; 00182 dump_algs(log,m_topAlgList); 00183 return true; 00184 } 00185 00186 00187 void DybDualEventLoopMgr::union_alg_list() 00188 { 00189 m_topAlgList.clear(); 00190 m_topAlgList.insert(m_topAlgList.end(), 00191 m_state1->topAlgList.begin(), 00192 m_state1->topAlgList.end()); 00193 if (m_state2->topAlgList.size()) { 00194 m_topAlgList.insert(m_topAlgList.end(), 00195 ++m_state2->topAlgList.begin(), 00196 m_state2->topAlgList.end()); 00197 } 00198 } 00199 00200 StatusCode DybDualEventLoopMgr::finalize() 00201 { 00202 MsgStream log(msgSvc(), name()); 00203 log << MSG::INFO << "A useless message about me finalizing" << endreq; 00204 00205 m_incsvc->removeListener(m_heiHandler,"HybridExecutionIncident"); 00206 delete m_heiHandler; m_heiHandler = 0; 00207 m_incsvc->release(); 00208 m_incsvc = 0; 00209 00210 union_alg_list(); 00211 return DybEventLoopMgr::finalize(); 00212 } 00213 00214 00215 StatusCode DybDualEventLoopMgr::reinitialize() 00216 { 00217 MsgStream log(msgSvc(), name()); 00218 log << MSG::WARNING << "Why am I being reinitialized?" << endreq; 00219 return StatusCode::SUCCESS; 00220 } 00221 00222 static void dump_tes(IDataManagerSvc* evtDataMgrSvc, MsgStream& log) 00223 { 00224 class Visitor : public IDataStoreAgent { 00225 public: 00226 MsgStream& log; 00227 int count; 00228 Visitor(MsgStream& lg) : log(lg), count(0) {} 00229 virtual ~Visitor() {} 00230 virtual bool analyse(IRegistry* pObject, int level) { 00231 ++count; 00232 log << MSG::DEBUG 00233 << count << ": " << pObject->name() 00234 << " @ " << level 00235 << " ref# " << pObject->object()->refCount() 00236 << endreq; 00237 return true; 00238 } 00239 } visitor(log); 00240 evtDataMgrSvc->traverseTree(&visitor); 00241 log << MSG::DEBUG 00242 << "Event data store now has " << visitor.count << " objects" 00243 << endreq; 00244 } 00245 00246 StatusCode DybDualEventLoopMgr::nextEvent(int maxevt) 00247 { 00248 StatusCode sc = StatusCode::SUCCESS; 00249 MsgStream log( msgSvc(), name() ); 00250 00251 log << MSG::DEBUG 00252 << "nextEvent(" << maxevt << ")" 00253 << endreq; 00254 00255 ListAlg save_topAlgList = m_topAlgList; 00256 00257 // force starting at state 1 00258 m_theState = m_state1; 00259 switch_state(true); 00260 00261 // loop over events if the maxevt (received as input) if different from -1. 00262 // if evtmax is -1 it means infinite loop 00263 int nevt = 0; 00264 bool been_here = false; 00265 while (true) { 00266 00267 switch_state(); 00268 00269 log << MSG::DEBUG 00270 << "Event #" << nevt 00271 << " in state " << (m_theState == m_state1 ? "one" : "two") 00272 << " with " << m_theState->topAlgList.size() << " algorithms" 00273 << endreq; 00274 dump_algs(log,m_theState->topAlgList); 00275 00276 if (m_theState == m_state2) { 00277 if (maxevt != -1 && nevt >= maxevt) { 00278 break; 00279 } 00280 ++nevt; 00281 } 00282 00283 log << MSG::DEBUG 00284 << "Executing event loop #" << nevt << endreq; 00285 00286 // Check if there is a scheduled stop issued by some algorithm/sevice 00287 if (m_scheduledStop) { 00288 m_scheduledStop = false; 00289 log << MSG::ALWAYS 00290 << "Terminating event processing loop due to scheduled stop" << endreq; 00291 m_topAlgList = save_topAlgList; 00292 return StatusCode::SUCCESS; 00293 } 00294 00295 if (true) { // this block is for debugging and can be turned off 00296 00297 // Want to avoid getting readout-phase objects tangled up 00298 // in AES and OHS. 00299 if (m_theState == m_state1) { 00300 log << MSG::DEBUG << "Inhibiting AES feeding" << endreq; 00301 m_aesfeed->inhibit(); 00302 } 00303 else { 00304 log << MSG::DEBUG << "Enabling AES feeding" << endreq; 00305 m_aesfeed->enable(); 00306 } 00307 00308 dump_tes(m_evtDataMgrSvc,log); 00309 } 00310 00311 if (been_here) { 00312 sc = m_evtDataMgrSvc->clearStore(); 00313 if (sc.isFailure()) { 00314 log << MSG::WARNING << "Clear of Event data store failed" << endreq; 00315 } 00316 log << MSG::DEBUG << "Cleared event store" << endreq; 00317 dump_tes(m_evtDataMgrSvc,log); 00318 } 00319 else { 00320 been_here = true; 00321 } 00322 // Setup event in the event store only in state1 00323 if (m_theState == m_state1 && m_evtContext) { 00324 IOpaqueAddress* addr = 0; 00325 // Only if there is a EventSelector 00326 sc = getEventRoot(addr); 00327 if (sc.isFailure()) { 00328 log << MSG::INFO << "No more events in event selection " << endreq; 00329 m_topAlgList = save_topAlgList; 00330 return StatusCode::SUCCESS; 00331 } 00332 00333 // Set root clears the event data store first 00334 sc = m_evtDataMgrSvc->setRoot("/Event", addr); 00335 if (sc.isFailure()) { 00336 log << MSG::WARNING << "Error declaring event root address." << endreq; 00337 continue; // not failure? 00338 } 00339 DataObject* pObject = 0; 00340 sc = m_evtDataSvc->retrieveObject("/Event", pObject); 00341 if( sc.isFailure() ) { 00342 log << MSG::WARNING << "Unable to retrieve Event root object" << endreq; 00343 m_topAlgList = save_topAlgList; 00344 return StatusCode::FAILURE; 00345 } 00346 } 00347 else { 00348 sc = m_evtDataMgrSvc->setRoot ("/Event", new DataObject()); 00349 if (sc.isFailure() ) { 00350 log << MSG::WARNING << "Error declaring event root DataObject" << endreq; 00351 } 00352 } 00353 // Execute event for all required algorithms 00354 sc = executeEvent(NULL); 00355 if (sc.isFailure()){ 00356 log << MSG::ERROR << "Terminating event processing loop due to errors" << endreq; 00357 m_topAlgList = save_topAlgList; 00358 return StatusCode::FAILURE; 00359 } 00360 } 00361 m_topAlgList = save_topAlgList; 00362 return StatusCode::SUCCESS; 00363 } 00364 00365 StatusCode DybDualEventLoopMgr::executeRun(int maxevt) 00366 { 00367 union_alg_list(); 00368 return MinimalEventLoopMgr::executeRun(maxevt); 00369 } 00370