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 discardDataEvent(MemRef_t* bufRef) const {
00136 std::cout
00137 << "RBStateMachine: current state does not support operation >>discardDataEvent<<"
00138 << std::endl;
00139
00140 return false;
00141 }
00142
00146 virtual bool discardDqmEvent(MemRef_t* bufRef) const {
00147 std::cout
00148 << "RBStateMachine: current state does not support operation >>discardDqmEvent<<"
00149 << std::endl;
00150
00151 return false;
00152 }
00153
00154
00155
00156
00157
00158
00162 virtual void do_stateNotify() = 0;
00163
00167 virtual int stateID() const = 0;
00168
00172 virtual void do_stateAction() const {
00173
00174
00175
00176
00177
00178 }
00179
00180 protected:
00181
00182 virtual std::string do_stateName() const = 0;
00183
00184 virtual void do_moveToFailedState(xcept::Exception& exception) const = 0;
00185 void fail();
00186
00187 void safeEntryAction();
00188 virtual void do_entryActionWork() = 0;
00189
00190 void safeExitAction();
00191 virtual void do_exitActionWork() = 0;
00192
00193 };
00194
00195
00201 class RBStateMachine: public bsc::state_machine<RBStateMachine, Normal> {
00202
00203 public:
00204
00205 RBStateMachine(xdaq::Application* app, SharedResourcesPtr_t sr);
00206 ~RBStateMachine();
00207
00212 BaseState const& getCurrentState() const throw (std::bad_cast);
00213
00214 BaseState & getCurrentStateNC() const throw (std::bad_cast);
00215
00216 inline SharedResourcesPtr_t getSharedResources() const {
00217 return sharedResources_;
00218 }
00219 inline std::string getExternallyVisibleState() {
00220 return visibleStateName_.value_;
00221 }
00222 inline xdata::String* getExternallyVisibleStatePtr() {
00223 return &visibleStateName_;
00224 }
00225 inline std::string getInternalStateName() {
00226 return internalStateName_;
00227 }
00228 inline xdaq::Application* getApp() const {
00229 return app_;
00230 }
00231 void setExternallyVisibleState(const std::string& s);
00232 void setInternalStateName(const std::string& s);
00236 inline bool firstTimeInHalted() const {
00237 return firstTimeInHalted_;
00238 }
00239 inline void setFirstTimeInHaltedFalse() {
00240 firstTimeInHalted_ = false;
00241 }
00242
00246 xdata::Bag<xdaq2rc::ClassnameAndInstance>* rcmsStateListener();
00250 xdata::Boolean* foundRcmsStateListener();
00251 void findRcmsStateListener(xdaq::Application* app);
00255 void rcmsStateChangeNotify();
00256
00257
00261 void transitionWriteLock() {
00262 pthread_rwlock_wrlock(&transitionLock_);
00263 }
00267 void transitionReadLock() {
00268 pthread_rwlock_rdlock(&transitionLock_);
00269 }
00273 void transitionUnlock() {
00274 pthread_rwlock_unlock(&transitionLock_);
00275 }
00276
00277 private:
00278 void updateWebGUIExternalState(std::string newStateName) const;
00279 void updateWebGUIInternalState(std::string newStateName) const;
00280
00281 private:
00282
00283 xdaq::Application* app_;
00284 SharedResourcesPtr_t sharedResources_;
00285 xdaq2rc::RcmsStateNotifier rcmsStateNotifier_;
00286 xdata::String visibleStateName_;
00287 std::string internalStateName_;
00288 bool firstTimeInHalted_;
00289
00290 pthread_rwlock_t transitionLock_;
00291 };
00292
00296
00297
00302 class Failed: public bsc::state<Failed, RBStateMachine>, public BaseState {
00303
00304 public:
00305
00306 Failed( my_context);
00307 virtual ~Failed();
00308
00309
00310 virtual void do_stateNotify();
00311
00312 virtual int stateID() const {
00313 return rb_statemachine::FAILED;
00314 }
00315
00316 private:
00317
00318 virtual std::string do_stateName() const;
00319 virtual void do_entryActionWork();
00320 virtual void do_exitActionWork();
00321 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00322
00323 };
00324
00325
00331 class Normal: public bsc::state<Normal, RBStateMachine, Halted>,
00332 public BaseState {
00333
00334 public:
00335
00336 typedef bsc::transition<Fail, Failed> FT;
00337 typedef boost::mpl::list<FT> reactions;
00338
00339
00340 virtual void do_stateNotify();
00341
00342 virtual int stateID() const {
00343 return rb_statemachine::NORMAL;
00344 }
00345
00346 Normal( my_context);
00347 virtual ~Normal();
00348
00349 private:
00350
00351 virtual std::string do_stateName() const;
00352 virtual void do_entryActionWork();
00353 virtual void do_exitActionWork();
00354 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00355 };
00356
00357
00363 class Halted: public bsc::state<Halted, Normal>, public BaseState {
00364
00365 public:
00366
00367 typedef bsc::transition<Configure, Configuring> RT;
00368 typedef boost::mpl::list<RT> reactions;
00369
00370
00371 virtual void do_stateNotify();
00372
00373 virtual int stateID() const {
00374 return rb_statemachine::HALTED;
00375 }
00376
00377 Halted( my_context);
00378 virtual ~Halted();
00379
00380 private:
00381
00382 virtual std::string do_stateName() const;
00383 virtual void do_entryActionWork();
00384 virtual void do_exitActionWork();
00385 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00386
00387 };
00388
00389
00395 class Configuring: public bsc::state<Configuring, Normal>, public BaseState {
00396
00397 public:
00398
00399 typedef bsc::transition<ConfigureDone, Ready> CR;
00400 typedef boost::mpl::list<CR> reactions;
00401
00402 Configuring( my_context);
00403 virtual ~Configuring();
00404
00405
00406 virtual void do_stateNotify();
00407 virtual int stateID() const {
00408 return rb_statemachine::CONFIGURING;
00409 }
00410 virtual void do_stateAction() const;
00411
00412 private:
00413
00417 void connectToBUandSM() const throw (evf::Exception);
00418
00419 private:
00420
00421 virtual std::string do_stateName() const;
00422 virtual void do_entryActionWork();
00423 virtual void do_exitActionWork();
00424 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00425
00426 };
00427
00428
00434 class Ready: public bsc::state<Ready, Normal, Stopped>, public BaseState {
00435
00436 public:
00437
00438 typedef bsc::transition<Halt, Halting> HT;
00439 typedef boost::mpl::list<HT> reactions;
00440
00441
00442 virtual void do_stateNotify();
00443
00444 virtual int stateID() const {
00445 return rb_statemachine::READY;
00446 }
00447
00448 Ready( my_context);
00449 virtual ~Ready();
00450
00451 private:
00452
00453 virtual std::string do_stateName() const;
00454 virtual void do_entryActionWork();
00455 virtual void do_exitActionWork();
00456 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00457
00458 };
00459
00460
00466 class Stopped: public bsc::state<Stopped, Ready>, public BaseState {
00467
00468 public:
00469
00470 typedef bsc::transition<Enable, Enabling> ET;
00471 typedef boost::mpl::list<ET> reactions;
00472
00473
00474 virtual void do_stateNotify();
00475
00476 virtual int stateID() const {
00477 return rb_statemachine::STOPPED;
00478 }
00479
00480 Stopped( my_context);
00481 virtual ~Stopped();
00482
00483 private:
00484
00485 virtual std::string do_stateName() const;
00486 virtual void do_entryActionWork();
00487 virtual void do_exitActionWork();
00488 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00489
00490 };
00491
00492
00498 class Enabling: public bsc::state<Enabling, Ready>,
00499 public BaseState,
00500 public toolbox::lang::Class {
00501
00502 public:
00503
00504 typedef bsc::transition<EnableDone, Enabled> ED;
00505 typedef boost::mpl::list<ED> reactions;
00506
00507 Enabling( my_context);
00508 virtual ~Enabling();
00509
00510
00511 virtual void do_stateNotify();
00512 virtual int stateID() const {
00513 return rb_statemachine::ENABLING;
00514 }
00515 virtual void do_stateAction() const;
00516
00517 private:
00518
00519 virtual std::string do_stateName() const;
00520 virtual void do_entryActionWork();
00521 virtual void do_exitActionWork();
00522 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00523
00524 };
00525
00526
00532 class Enabled: public bsc::state<Enabled, Ready, Running>, public BaseState {
00533
00534 public:
00535
00536 typedef bsc::transition<Stop, Stopping> ST;
00537 typedef boost::mpl::list<ST> reactions;
00538
00539
00540 virtual void do_stateNotify();
00541
00542 virtual int stateID() const {
00543 return rb_statemachine::ENABLED;
00544 }
00545
00546 Enabled( my_context);
00547 virtual ~Enabled();
00548
00549 private:
00550
00551 virtual std::string do_stateName() const;
00552 virtual void do_entryActionWork();
00553 virtual void do_exitActionWork();
00554 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00555
00556 };
00557
00558
00564 class Running: public bsc::state<Running, Enabled>,
00565 public BaseState,
00566 public toolbox::lang::Class {
00567
00568 public:
00569
00570 Running( my_context);
00571 virtual ~Running();
00572
00573
00574 virtual bool discardDataEvent(MemRef_t* bufRef) const;
00575 virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00576
00577
00578 virtual void do_stateNotify();
00579 virtual void do_stateAction() const;
00580 virtual int stateID() const {
00581 return rb_statemachine::RUNNING;
00582 }
00583
00584 private:
00585
00586 virtual std::string do_stateName() const;
00587 virtual void do_entryActionWork();
00588 virtual void do_exitActionWork();
00589 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00590 };
00591
00592
00598 class Stopping: public bsc::state<Stopping, Ready>, public BaseState {
00599
00600 public:
00601
00602 typedef bsc::transition<StopDone, Stopped> SD;
00603 typedef boost::mpl::list<SD> reactions;
00604
00605 Stopping( my_context);
00606 virtual ~Stopping();
00607
00608
00609 virtual bool discardDataEvent(MemRef_t* bufRef) const;
00610 virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00611
00612
00613 virtual void do_stateNotify();
00614 virtual int stateID() const {
00615 return rb_statemachine::STOPPING;
00616 }
00617 virtual void do_stateAction() const;
00618
00619 private:
00620
00621 void emergencyStop() const;
00622
00623 private:
00624
00625 virtual std::string do_stateName() const;
00626 virtual void do_entryActionWork();
00627 virtual void do_exitActionWork();
00628 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00629
00630 bool destructionIsDone() const;
00631 };
00632
00633
00639 class Halting: public bsc::state<Halting, Normal>, public BaseState {
00640
00641 public:
00642
00643 typedef bsc::transition<HaltDone, Halted> HD;
00644 typedef boost::mpl::list<HD> reactions;
00645
00646 Halting( my_context);
00647 virtual ~Halting();
00648
00649
00650 virtual bool discardDataEvent(MemRef_t* bufRef) const;
00651 virtual bool discardDqmEvent(MemRef_t* bufRef) const;
00652
00653
00654 virtual void do_stateNotify();
00655 virtual int stateID() const {
00656 return rb_statemachine::HALTING;
00657 }
00658 virtual void do_stateAction() const;
00659
00660 private:
00661
00662 virtual std::string do_stateName() const;
00663 virtual void do_entryActionWork();
00664 virtual void do_exitActionWork();
00665 virtual void do_moveToFailedState(xcept::Exception& exception) const;
00666
00667 bool destructionIsDone() const;
00668
00669 void doAsync() const;
00670
00671 };
00672
00673 typedef boost::shared_ptr<RBStateMachine> RBStateMachinePtr;
00674
00675 }
00676
00677 }
00678
00679 #endif