00001 00002 // 00003 // SMEventScheduler.h 00004 // ------- 00005 // 00006 // Holds and executes a list FIFO of FSM transition events. 00007 // 00008 // Created on: Dec 13, 2011 00009 // Andrei Spataru : aspataru@cern.ch 00011 00012 #include "EventFilter/ResourceBroker/interface/SMEventScheduler.h" 00013 00014 #include <string> 00015 #include <iostream> 00016 00017 using namespace evf::rb_statemachine; 00018 using namespace evf; 00019 00020 using std::string; 00021 using std::cout; 00022 using std::endl; 00023 00024 SMEventScheduler::SMEventScheduler(RBStateMachinePtr fsm, CommandQueue& comms) : 00025 fsm_(fsm), commands_(comms), continueWorkloop_(true) { 00026 00027 startSchedulerWorkloop(); 00028 } 00029 00030 SMEventScheduler::~SMEventScheduler() { 00031 stopScheduling(); 00032 } 00033 00034 //______________________________________________________________________________ 00035 void SMEventScheduler::startSchedulerWorkloop() throw (evf::Exception) { 00036 try { 00037 //improve log instead of cout 00038 cout << "Start 'SCHEDULER EVENT PROCESSING' workloop" << endl; 00039 wlProcessingEvents_ = toolbox::task::getWorkLoopFactory()->getWorkLoop( 00040 "Scheduler Processing Events", "waiting"); 00041 if (!wlProcessingEvents_->isActive()) 00042 wlProcessingEvents_->activate(); 00043 asProcessingEvents_ = toolbox::task::bind(this, 00044 &SMEventScheduler::processing, "SchedulerProcessing"); 00045 wlProcessingEvents_->submit(asProcessingEvents_); 00046 } catch (xcept::Exception& e) { 00047 string msg = "Failed to start workloop 'SCHEDULER EVENT PROCESSING'."; 00048 //improve log instead of cout 00049 cout << msg << endl; 00050 } 00051 } 00052 00053 //______________________________________________________________________________ 00054 bool SMEventScheduler::processing(toolbox::task::WorkLoop* wl) { 00055 // deqEvent() blocks until a command is present in the queue 00056 EventPtr topEvent = commands_.deqEvent(); 00057 00058 // 0. lock state transition 00059 fsm_->transitionWriteLock(); 00060 // 1. process top event from the queue 00061 fsm_->process_event(*topEvent); 00062 // 1.5 unlock state transition 00063 fsm_->transitionUnlock(); 00064 00065 // 2. update state of the FSM, also notifying RCMS 00066 /* 00067 * XXX casting away constness for the state Notification call 00068 * done because state stateChanged in rcmsStateListener is not const 00069 * stateNotify does not change BaseState& so operation is safe 00070 */ 00071 const_cast<BaseState&> (fsm_->getCurrentState()).do_stateNotify(); 00072 00073 // 3. perform state-specific action 00074 fsm_->getCurrentState().do_stateAction(); 00075 00076 return continueWorkloop_; 00077 }