From 24d26e802a841decd2865517edbfb233717da155 Mon Sep 17 00:00:00 2001 From: Thorsten Kollegger Date: Sat, 26 Apr 2014 10:11:39 +0000 Subject: [PATCH] Using boost::msm inside FairMQStateMachine. --- fairmq/FairMQStateMachine.cxx | 183 +++++---------------------- fairmq/FairMQStateMachine.h | 224 +++++++++++++++++++++++++++++++--- 2 files changed, 236 insertions(+), 171 deletions(-) diff --git a/fairmq/FairMQStateMachine.cxx b/fairmq/FairMQStateMachine.cxx index a5ab4282..04516b18 100644 --- a/fairmq/FairMQStateMachine.cxx +++ b/fairmq/FairMQStateMachine.cxx @@ -5,166 +5,43 @@ * @author D. Klein, A. Rybalchenko */ -#include -#include - #include "FairMQStateMachine.h" #include "FairMQLogger.h" - -FairMQStateMachine::FairMQStateMachine() : - fState(IDLE) -{ -} - -void FairMQStateMachine::ChangeState(int event) -{ - switch(fState) { - - case IDLE: - switch(event) { - - case INIT: - LOG(STATE) << "IDLE --init--> INITIALIZING"; - fState = INITIALIZING; - Init(); - return; - - case END: - LOG(STATE) << "IDLE --end--> (o)"; - return; - - default: - return; - } - break; - - - case INITIALIZING: - switch(event) { - - case SETOUTPUT: - LOG(STATE) << "INITIALIZING --bind--> SETTINGOUTPUT"; - fState = SETTINGOUTPUT; - InitOutput(); - return; - - default: - return; - } - break; - - - case SETTINGOUTPUT: - switch(event) { - - case SETINPUT: - LOG(STATE) << "SETTINGOUTPUT --connect--> SETTINGINPUT"; - fState = SETTINGINPUT; - InitInput(); - return; - - default: - return; - } - break; - - - case SETTINGINPUT: - switch(event) { - - case PAUSE: - LOG(STATE) << "SETTINGINPUT --pause--> WAITING"; - fState = WAITING; - Pause(); - return; - - case RUN: - LOG(STATE) << "SETTINGINPUT --run--> RUNNING"; - fState = RUNNING; - running_state = boost::thread(boost::bind(&FairMQStateMachine::Run, this)); - return; - - default: - return; - } - break; - - - case WAITING: - switch(event) { - - case RUN: - LOG(STATE) << "WAITING --run--> RUNNING"; - fState = RUNNING; - running_state = boost::thread(boost::bind(&FairMQStateMachine::Run, this)); - return; - - case STOP: - LOG(STATE) << "WAITING --stop--> IDLE"; - fState = IDLE; - Shutdown(); - return; - - default: - return; - } - break; - - - case RUNNING: - switch(event) { - - case PAUSE: - LOG(STATE) << "RUNNING --pause--> WAITING"; - fState = WAITING; - running_state.join(); - return; - - case STOP: - LOG(STATE) << "RUNNING --stop--> IDLE"; - fState = IDLE; - running_state.join(); - Shutdown(); - return; - - default: - return; - } - break; - - - default: - break; - - }//switch fState -} - -void FairMQStateMachine::Init() -{ -} - -void FairMQStateMachine::Run() -{ -} - -void FairMQStateMachine::Pause() -{ -} - -void FairMQStateMachine::Shutdown() -{ -} - -void FairMQStateMachine::InitOutput() -{ -} - -void FairMQStateMachine::InitInput() +FairMQStateMachine::FairMQStateMachine() { + start(); } FairMQStateMachine::~FairMQStateMachine() { + stop(); } +void FairMQStateMachine::ChangeState(int event) +{ + switch (event) + { + case INIT: + process_event(FairMQFSM::INIT()); + return; + case SETOUTPUT: + process_event(FairMQFSM::SETOUTPUT()); + return; + case SETINPUT: + process_event(FairMQFSM::SETINPUT()); + return; + case RUN: + process_event(FairMQFSM::RUN()); + return; + case PAUSE: + process_event(FairMQFSM::PAUSE()); + return; + case STOP: + process_event(FairMQFSM::STOP()); + return; + case END: + process_event(FairMQFSM::END()); + return; + } +} diff --git a/fairmq/FairMQStateMachine.h b/fairmq/FairMQStateMachine.h index 2cd015be..70177663 100644 --- a/fairmq/FairMQStateMachine.h +++ b/fairmq/FairMQStateMachine.h @@ -9,31 +9,219 @@ #define FAIRMQSTATEMACHINE_H_ #include +#include +#include +#include +#include +#include +#include +#include +#include "FairMQLogger.h" -class FairMQStateMachine +namespace msm = boost::msm; +namespace mpl = boost::mpl; +namespace msmf = boost::msm::front; + +namespace FairMQFSM +{ + // defining events for the boost MSM state machine + struct INIT + { + }; + struct SETOUTPUT + { + }; + struct SETINPUT + { + }; + struct PAUSE + { + }; + struct RUN + { + }; + struct STOP + { + }; + struct END + { + }; + + // defining the boost MSM state machine + struct FairMQFSM_ : public msm::front::state_machine_def + { + template + void on_entry(Event const&, FSM&) + { + LOG(STATE) << "Entering FairMQ state machine"; + fState = IDLE; + } + template + void on_exit(Event const&, FSM&) + { + LOG(STATE) << "Exiting FairMQ state machine"; + } + // The list of FSM states + struct IDLE_FSM : public msm::front::state<> + { + }; + struct INITIALIZING_FSM : public msm::front::state<> + { + }; + struct SETTINGOUTPUT_FSM : public msm::front::state<> + { + }; + struct SETTINGINPUT_FSM : public msm::front::state<> + { + }; + struct WAITING_FSM : public msm::front::state<> + { + }; + struct RUNNING_FSM : public msm::front::state<> + { + }; + // Define initial state + typedef IDLE_FSM initial_state; + // Actions + struct TestFct + { + template + void operator()(EVT const&, FSM&, SourceState&, TargetState&) + { + LOG(STATE) << "Transition from " << typeid(SourceState).name() << " to " << typeid(TargetState).name() << " with event:" << typeid(EVT).name(); + } + }; + struct InitFct + { + template + void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) + { + fsm.fState = INITIALIZING; + fsm.Init(); + } + }; + struct SetOutputFct + { + template + void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) + { + fsm.fState = SETTINGOUTPUT; + fsm.InitOutput(); + } + }; + struct SetInputFct + { + template + void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) + { + fsm.fState = SETTINGINPUT; + fsm.InitInput(); + } + }; + struct RunFct + { + template + void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) + { + fsm.fState = RUNNING; + fsm.running_state = boost::thread(boost::bind(&FairMQFSM_::Run, &fsm)); + } + }; + struct StopFct + { + template + void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) + { + fsm.fState = IDLE; + fsm.running_state.join(); + fsm.Shutdown(); + } + }; + struct PauseFct + { + template + void operator()(EVT const&, FSM& fsm, SourceState&, TargetState&) + { + fsm.fState = WAITING; + fsm.running_state.join(); + fsm.Pause(); + } + }; + // actions to be overwritten by derived classes + virtual void Init() + { + } + virtual void Run() + { + } + virtual void Pause() + { + } + virtual void Shutdown() + { + } + virtual void InitOutput() + { + } + virtual void InitInput() + { + } + // Transition table for FairMQFMS + struct transition_table : mpl::vector< + // Start Event Next Action Guard + // +---------+---------+-------+---------+--------+ + msmf::Row, + msmf::Row, // this is an invalid transition... + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row, + msmf::Row > + { + }; + // Replaces the default no-transition response. + template + void no_transition(Event const& e, FSM&, int state) + { + LOG(STATE) << "no transition from state " << state << " on event " << typeid(e).name() << std::endl; + } + // this is to run certain functions (e.g. Run()) as separate task + boost::thread running_state; + // backward compatibility to FairMQStateMachine + enum State + { + IDLE, + INITIALIZING, + SETTINGOUTPUT, + SETTINGINPUT, + WAITING, + RUNNING + }; + State fState; + }; + typedef msm::back::state_machine FairMQFSM; +} + +class FairMQStateMachine : public FairMQFSM::FairMQFSM { public: - enum State { - IDLE, INITIALIZING, SETTINGOUTPUT, SETTINGINPUT, WAITING, RUNNING - }; - enum Event { - INIT, SETOUTPUT, SETINPUT, PAUSE, RUN, STOP, END + enum Event + { + INIT, + SETOUTPUT, + SETINPUT, + PAUSE, + RUN, + STOP, + END }; FairMQStateMachine(); - void ChangeState(int event); virtual ~FairMQStateMachine(); - - protected: - State fState; - Event fEvent; - virtual void Init(); - virtual void Run(); - virtual void Pause(); - virtual void Shutdown(); - virtual void InitOutput(); - virtual void InitInput(); - boost::thread running_state; + void ChangeState(int event); }; #endif /* FAIRMQSTATEMACHINE_H_ */