00001
00002
00003
00004
00005
00006
00007
00008
00009
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
00068 class Failed;
00069 class Normal;
00070
00071
00072 class Halted;
00073 class Halting;
00074 class Configuring;
00075 class Ready;
00076
00077
00078 class Stopped;
00079 class Enabled;
00080 class Enabling;
00081
00082 class Stopping;
00083
00084
00085
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
00130
00131
00135 virtual bool take(toolbox::mem::Reference* bufRef) const {
00136
00137 return false;
00138 }
00142 virtual bool evmLumisection(toolbox::mem::Reference* bufRef) const {
00143
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
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
00165 return false;
00166 }
00167
00168
00169
00170
00171
00172
00176 virtual void do_stateNotify() = 0;
00177
00181 virtual int stateID() const = 0;
00182
00186 virtual void do_stateAction() const {
00187
00188
00189
00190
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
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
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
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
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
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
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
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
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
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
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
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
00622 virtual bool discardDataEvent(MemRef_t* bufRef) const;
00623 virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00624
00625
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
00663 virtual bool discardDataEvent(MemRef_t* bufRef) const;
00664 virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00665
00666
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 }
00689
00690 }
00691
00692 #endif