CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_1/src/EventFilter/ResourceBroker/interface/RBStateMachine.h

Go to the documentation of this file.
00001 
00002 //
00003 // RBStateMachine.h
00004 // -------
00005 //
00006 // Finite state machine for the Resource Broker.
00007 //
00008 //  Created on: Dec 9, 2011
00009 //                                                                              Andrei Spataru : aspataru@cern.ch
00011 
00012 #ifndef RBBOOSTSTATEMACHINE_H_
00013 #define RBBOOSTSTATEMACHINE_H_
00014 
00015 #include "EventFilter/Utilities/interface/Exception.h"
00016 #include "EventFilter/ResourceBroker/interface/FUTypes.h"
00017 
00018 #include "xdaq2rc/RcmsStateNotifier.h"
00019 #include "xdata/String.h"
00020 #include "xdata/Bag.h"
00021 #include "xdaq/Application.h"
00022 
00023 #include <boost/statechart/event.hpp>
00024 #include <boost/statechart/in_state_reaction.hpp>
00025 #include <boost/statechart/state_machine.hpp>
00026 #include <boost/statechart/state.hpp>
00027 #include <boost/statechart/transition.hpp>
00028 #include <boost/mpl/list.hpp>
00029 #include <boost/shared_ptr.hpp>
00030 
00031 #include "toolbox/task/Action.h"
00032 #include "toolbox/task/WorkLoop.h"
00033 #include "toolbox/task/WorkLoopFactory.h"
00034 
00035 #include <iostream>
00036 #include <string>
00037 #include <vector>
00038 #include <semaphore.h>
00039 
00040 namespace bsc = boost::statechart;
00041 
00042 namespace evf {
00043 
00044 namespace rb_statemachine {
00045 
00046 enum States {
00047         HALTED,
00048         CONFIGURING,
00049         READY,
00050         STOPPED,
00051         ENABLING,
00052         ENABLED,
00053         RUNNING,
00054         STOPPING,
00055         HALTING,
00056         NORMAL,
00057         FAILED
00058 };
00059 
00060 class SharedResources;
00061 typedef boost::shared_ptr<SharedResources> SharedResourcesPtr_t;
00062 
00066 
00067 // Outer states:
00068 class Failed;
00069 class Normal;
00070 
00071 // Inner states of Normal:
00072 class Halted;
00073 class Halting;
00074 class Configuring;
00075 class Ready;
00076 
00077 // Inner states of Ready:
00078 class Stopped;
00079 class Enabled;
00080 class Enabling;
00081 // state hidden from RCMS
00082 class Stopping;
00083 
00084 // Inner states of Enabled:
00085 // state hidden from RCMS
00086 class Running;
00087 
00091 
00092 class Configure: public bsc::event<Configure> {
00093 };
00094 class ConfigureDone: public bsc::event<ConfigureDone> {
00095 };
00096 class Enable: public bsc::event<Enable> {
00097 };
00098 class EnableDone: public bsc::event<EnableDone> {
00099 };
00100 class Stop: public bsc::event<Stop> {
00101 };
00102 class StopDone: public bsc::event<StopDone> {
00103 };
00104 class Halt: public bsc::event<Halt> {
00105 };
00106 class HaltDone: public bsc::event<HaltDone> {
00107 };
00108 class Fail: public bsc::event<Fail> {
00109 };
00110 
00111 //______________________________________________________________________________
00119 class BaseState {
00120 
00121 public:
00122 
00123         BaseState();
00124         virtual ~BaseState() = 0;
00125         std::string stateName() const;
00126         void moveToFailedState(xcept::Exception& exception) const;
00127 
00128         /*
00129          * I2O message handling capability of states.
00130          * All states with special behavior must override these functions.
00131          */
00135         virtual bool take(toolbox::mem::Reference* bufRef) const {
00136                 // output message handled in FUResourceBroker
00137                 return false;
00138         }
00142         virtual bool evmLumisection(toolbox::mem::Reference* bufRef) const {
00143                 // output message handled in FUResourceBroker
00144                 return false;
00145         }
00149         virtual bool discardDataEvent(MemRef_t* bufRef) const {
00150                 std::cout
00151                                 << "RBStateMachine: current state does not support operation >>discardDataEvent<<"
00152                                 << std::endl;
00153                 // bool value doesn't matter... return value ignored by caller: FUResourceBroker
00154                 return false;
00155         }
00156 
00160         virtual bool discardDqmEvent(MemRef_t* bufRef) const {
00161                 std::cout
00162                                 << "RBStateMachine: current state does not support operation >>discardDqmEvent<<"
00163                                 << std::endl;
00164                 // bool value doesn't matter... return value ignored by caller: FUResourceBroker
00165                 return false;
00166         }
00167 
00168         /*
00169          * DEFAULT implementations of state-dependent actions.
00170          * All states with special behavior must override these functions.
00171          */
00172 
00176         virtual void do_stateNotify() = 0;
00177 
00181         virtual int stateID() const = 0;
00182 
00186         virtual void do_stateAction() const {
00187                 // do nothing if state does not override this function
00188                 /*
00189                  std::cout << "RBStateMachine: no >>STATE ACTION<< defined for state: "
00190                  << stateName() << std::endl;
00191                  */
00192         }
00193 
00194 protected:
00195 
00196         virtual std::string do_stateName() const = 0;
00197 
00198         virtual void do_moveToFailedState(xcept::Exception& exception) const = 0;
00199         void fail();
00200 
00201         void safeEntryAction();
00202         virtual void do_entryActionWork() = 0;
00203 
00204         void safeExitAction();
00205         virtual void do_exitActionWork() = 0;
00206 
00207 };
00208 
00209 //______________________________________________________________________________
00215 class RBStateMachine: public bsc::state_machine<RBStateMachine, Normal> {
00216 
00217 public:
00218 
00219         RBStateMachine(xdaq::Application* app, SharedResourcesPtr_t sr);
00220         ~RBStateMachine();
00221 
00226         BaseState const& getCurrentState() const throw (std::bad_cast);
00227 
00228         inline SharedResourcesPtr_t getSharedResources() const {
00229                 return sharedResources_;
00230         }
00231         inline std::string getExternallyVisibleState() {
00232                 return visibleStateName_.value_;
00233         }
00234         inline xdata::String* getExternallyVisibleStatePtr() {
00235                 return &visibleStateName_;
00236         }
00237         inline std::string getInternalStateName() {
00238                 return internalStateName_;
00239         }
00240         inline xdaq::Application* getApp() const {
00241                 return app_;
00242         }
00243         void setExternallyVisibleState(const std::string& s);
00244         void setInternalStateName(const std::string& s);
00248         inline bool firstTimeInHalted() const {
00249                 return firstTimeInHalted_;
00250         }
00251         inline void setFirstTimeInHaltedFalse() {
00252                 firstTimeInHalted_ = false;
00253         }
00254 
00258         xdata::Bag<xdaq2rc::ClassnameAndInstance>* rcmsStateListener();
00262         xdata::Boolean* foundRcmsStateListener();
00263         void findRcmsStateListener(xdaq::Application* app);
00267         void rcmsStateChangeNotify();
00268 
00269         // state-transition safety
00273         void transitionWriteLock() {
00274                 pthread_rwlock_wrlock(&transitionLock_);
00275         }
00279         void transitionReadLock() {
00280                 pthread_rwlock_rdlock(&transitionLock_);
00281         }
00285         void transitionUnlock() {
00286                 pthread_rwlock_unlock(&transitionLock_);
00287         }
00288 
00289 private:
00290         void updateWebGUIExternalState(std::string newStateName) const;
00291         void updateWebGUIInternalState(std::string newStateName) const;
00292 
00293 private:
00294 
00295         xdaq::Application* app_;
00296         SharedResourcesPtr_t sharedResources_;
00297         xdaq2rc::RcmsStateNotifier rcmsStateNotifier_;
00298         xdata::String visibleStateName_;
00299         std::string internalStateName_;
00300         bool firstTimeInHalted_;
00301 
00302         pthread_rwlock_t transitionLock_;
00303 };
00304 
00308 
00309 //______________________________________________________________________________
00314 class Failed: public bsc::state<Failed, RBStateMachine>, public BaseState {
00315 
00316 public:
00317 
00318         Failed( my_context);
00319         virtual ~Failed();
00320 
00321         // state-dependent actions
00322         virtual void do_stateNotify();
00323 
00324         virtual int stateID() const {
00325                 return rb_statemachine::FAILED;
00326         }
00327 
00328 private:
00329 
00330         virtual std::string do_stateName() const;
00331         virtual void do_entryActionWork();
00332         virtual void do_exitActionWork();
00333         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00334 
00335 };
00336 
00337 //______________________________________________________________________________
00343 class Normal: public bsc::state<Normal, RBStateMachine, Halted>,
00344                 public BaseState {
00345 
00346 public:
00347 
00348         typedef bsc::transition<Fail, Failed> FT;
00349         typedef boost::mpl::list<FT> reactions;
00350 
00351         // state-dependent actions
00352         virtual void do_stateNotify();
00353 
00354         virtual int stateID() const {
00355                 return rb_statemachine::NORMAL;
00356         }
00357 
00358         Normal( my_context);
00359         virtual ~Normal();
00360 
00361 private:
00362 
00363         virtual std::string do_stateName() const;
00364         virtual void do_entryActionWork();
00365         virtual void do_exitActionWork();
00366         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00367 };
00368 
00369 //______________________________________________________________________________
00375 class Halted: public bsc::state<Halted, Normal>, public BaseState {
00376 
00377 public:
00378 
00379         typedef bsc::transition<Configure, Configuring> RT;
00380         typedef boost::mpl::list<RT> reactions;
00381 
00382         // state-dependent actions
00383         virtual void do_stateNotify();
00384 
00385         virtual int stateID() const {
00386                 return rb_statemachine::HALTED;
00387         }
00388 
00389         Halted( my_context);
00390         virtual ~Halted();
00391 
00392 private:
00393 
00394         virtual std::string do_stateName() const;
00395         virtual void do_entryActionWork();
00396         virtual void do_exitActionWork();
00397         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00398 
00399 };
00400 
00401 //______________________________________________________________________________
00407 class Configuring: public bsc::state<Configuring, Normal>, public BaseState {
00408 
00409 public:
00410 
00411         typedef bsc::transition<ConfigureDone, Ready> CR;
00412         typedef boost::mpl::list<CR> reactions;
00413 
00414         Configuring( my_context);
00415         virtual ~Configuring();
00416 
00417         // state-dependent actions
00418         virtual void do_stateNotify();
00419         virtual int stateID() const {
00420                 return rb_statemachine::CONFIGURING;
00421         }
00422         virtual void do_stateAction() const;
00423 
00424 private:
00425 
00429         void connectToBUandSM() const throw (evf::Exception);
00430 
00431 private:
00432 
00433         virtual std::string do_stateName() const;
00434         virtual void do_entryActionWork();
00435         virtual void do_exitActionWork();
00436         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00437 
00438 };
00439 
00440 //______________________________________________________________________________
00446 class Ready: public bsc::state<Ready, Normal, Stopped>, public BaseState {
00447 
00448 public:
00449 
00450         typedef bsc::transition<Halt, Halting> HT;
00451         typedef boost::mpl::list<HT> reactions;
00452 
00453         // state-dependent actions
00454         virtual void do_stateNotify();
00455 
00456         virtual int stateID() const {
00457                 return rb_statemachine::READY;
00458         }
00459 
00460         Ready( my_context);
00461         virtual ~Ready();
00462 
00463 private:
00464 
00465         virtual std::string do_stateName() const;
00466         virtual void do_entryActionWork();
00467         virtual void do_exitActionWork();
00468         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00469 
00470 };
00471 
00472 //______________________________________________________________________________
00478 class Stopped: public bsc::state<Stopped, Ready>, public BaseState {
00479 
00480 public:
00481 
00482         typedef bsc::transition<Enable, Enabling> ET;
00483         typedef boost::mpl::list<ET> reactions;
00484 
00485         // state-dependent actions
00486         virtual void do_stateNotify();
00487 
00488         virtual int stateID() const {
00489                 return rb_statemachine::STOPPED;
00490         }
00491 
00492         Stopped( my_context);
00493         virtual ~Stopped();
00494 
00495 private:
00496 
00497         virtual std::string do_stateName() const;
00498         virtual void do_entryActionWork();
00499         virtual void do_exitActionWork();
00500         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00501 
00502 };
00503 
00504 //______________________________________________________________________________
00510 class Enabling: public bsc::state<Enabling, Ready>,
00511                 public BaseState,
00512                 public toolbox::lang::Class {
00513 
00514 public:
00515 
00516         typedef bsc::transition<EnableDone, Enabled> ED;
00517         typedef boost::mpl::list<ED> reactions;
00518 
00519         Enabling( my_context);
00520         virtual ~Enabling();
00521 
00522         // state-dependent actions
00523         virtual void do_stateNotify();
00524         virtual int stateID() const {
00525                 return rb_statemachine::ENABLING;
00526         }
00527         virtual void do_stateAction() const;
00528 
00529 private:
00530 
00531         virtual std::string do_stateName() const;
00532         virtual void do_entryActionWork();
00533         virtual void do_exitActionWork();
00534         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00535 
00536 };
00537 
00538 //______________________________________________________________________________
00544 class Enabled: public bsc::state<Enabled, Ready, Running>, public BaseState {
00545 
00546 public:
00547 
00548         typedef bsc::transition<Stop, Stopping> ST;
00549         typedef boost::mpl::list<ST> reactions;
00550 
00551         // state-dependent actions
00552         virtual void do_stateNotify();
00553 
00554         virtual int stateID() const {
00555                 return rb_statemachine::ENABLED;
00556         }
00557 
00558         Enabled( my_context);
00559         virtual ~Enabled();
00560 
00561 private:
00562 
00563         virtual std::string do_stateName() const;
00564         virtual void do_entryActionWork();
00565         virtual void do_exitActionWork();
00566         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00567 
00568 };
00569 
00570 //______________________________________________________________________________
00576 class Running: public bsc::state<Running, Enabled>,
00577                 public BaseState,
00578                 public toolbox::lang::Class {
00579 
00580 public:
00581 
00582         Running( my_context);
00583         virtual ~Running();
00584 
00585         // I2O message handling capability of state
00586         virtual bool take(toolbox::mem::Reference* bufRef) const;
00587         virtual bool evmLumisection(toolbox::mem::Reference* bufRef) const;
00588         virtual bool discardDataEvent(MemRef_t* bufRef) const;
00589         virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00590 
00591         // state-dependent actions
00592         virtual void do_stateNotify();
00593         virtual int stateID() const {
00594                 return rb_statemachine::RUNNING;
00595         }
00596 
00597 private:
00598 
00599         virtual std::string do_stateName() const;
00600         virtual void do_entryActionWork();
00601         virtual void do_exitActionWork();
00602         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00603 };
00604 
00605 //______________________________________________________________________________
00611 class Stopping: public bsc::state<Stopping, Ready>, public BaseState {
00612 
00613 public:
00614 
00615         typedef bsc::transition<StopDone, Stopped> SD;
00616         typedef boost::mpl::list<SD> reactions;
00617 
00618         Stopping( my_context);
00619         virtual ~Stopping();
00620 
00621         //I2O capability
00622         virtual bool discardDataEvent(MemRef_t* bufRef) const;
00623         virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00624 
00625         // state-dependent actions
00626         virtual void do_stateNotify();
00627         virtual int stateID() const {
00628                 return rb_statemachine::STOPPING;
00629         }
00630         virtual void do_stateAction() const;
00631 
00632 private:
00633 
00634         void emergencyStop() const;
00635 
00636 private:
00637 
00638         virtual std::string do_stateName() const;
00639         virtual void do_entryActionWork();
00640         virtual void do_exitActionWork();
00641         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00642 
00643         bool destructionIsDone() const;
00644 };
00645 
00646 //______________________________________________________________________________
00652 class Halting: public bsc::state<Halting, Normal>, public BaseState {
00653 
00654 public:
00655 
00656         typedef bsc::transition<HaltDone, Halted> HD;
00657         typedef boost::mpl::list<HD> reactions;
00658 
00659         Halting( my_context);
00660         virtual ~Halting();
00661 
00662         //I2O capability
00663         virtual bool discardDataEvent(MemRef_t* bufRef) const;
00664         virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00665 
00666         // state-dependent actions
00667         virtual void do_stateNotify();
00668         virtual int stateID() const {
00669                 return rb_statemachine::HALTING;
00670         }
00671         virtual void do_stateAction() const;
00672 
00673 private:
00674 
00675         virtual std::string do_stateName() const;
00676         virtual void do_entryActionWork();
00677         virtual void do_exitActionWork();
00678         virtual void do_moveToFailedState(xcept::Exception& exception) const;
00679 
00680         bool destructionIsDone() const;
00681 
00682         void doAsync() const;
00683 
00684 };
00685 
00686 typedef boost::shared_ptr<RBStateMachine> RBStateMachinePtr;
00687 
00688 } // end namespace rb_statemachine
00689 
00690 } // end namespace evf
00691 
00692 #endif /* RBBOOSTSTATEMACHINE_H_ */