00001
00003
00004 #ifndef EventFilter_SMProxyServer_States_h
00005 #define EventFilter_SMProxyServer_States_h
00006
00007 #include "EventFilter/SMProxyServer/interface/Exception.h"
00008
00009 #include "xcept/Exception.h"
00010
00011 #include <boost/mpl/list.hpp>
00012 #include <boost/thread/thread.hpp>
00013 #include <boost/scoped_ptr.hpp>
00014 #include <boost/statechart/custom_reaction.hpp>
00015 #include <boost/statechart/event.hpp>
00016 #include <boost/statechart/state.hpp>
00017 #include <boost/statechart/transition.hpp>
00018
00019 #include <string>
00020
00021
00022 namespace smproxy
00023 {
00024
00026
00028
00029
00030 class Failed;
00031 class AllOk;
00032
00033 class Constructed;
00034 class Halted;
00035 class Configuring;
00036 class Ready;
00037 class Enabled;
00038 class Stopping;
00039 class Halting;
00040
00041 class Starting;
00042 class Running;
00043
00044
00046
00048
00049 class ConfiguringDone: public boost::statechart::event<ConfiguringDone> {};
00050 class StartingDone: public boost::statechart::event<StartingDone> {};
00051 class StoppingDone: public boost::statechart::event<StoppingDone> {};
00052 class HaltingDone: public boost::statechart::event<HaltingDone> {};
00053
00054
00056
00058
00059 template< class MostDerived,
00060 class Context,
00061 class InnerInitial = boost::mpl::list<>,
00062 boost::statechart::history_mode historyMode = boost::statechart::has_no_history >
00063 class State : public StateName,
00064 public boost::statechart::state<MostDerived, Context, InnerInitial, historyMode>
00065 {
00066 public:
00067 std::string stateName() const
00068 { return stateName_; }
00069
00070 protected:
00071 typedef boost::statechart::state<MostDerived, Context, InnerInitial, historyMode> boost_state;
00072 typedef State my_state;
00073
00074 State(const std::string stateName, typename boost_state::my_context& c) :
00075 boost_state(c), stateName_(stateName) {};
00076 virtual ~State() {};
00077
00078 virtual void entryAction() {};
00079 virtual void exitAction() {};
00080
00081 const std::string stateName_;
00082
00083 void safeEntryAction()
00084 {
00085 std::string msg = "Failed to enter " + stateName_ + " state";
00086 try
00087 {
00088 entryAction();
00089 }
00090 catch( xcept::Exception& e )
00091 {
00092 XCEPT_DECLARE_NESTED(exception::StateTransition,
00093 sentinelException, msg, e );
00094 this->post_event( Fail(sentinelException) );
00095 }
00096 catch( std::exception& e )
00097 {
00098 msg += ": ";
00099 msg += e.what();
00100 XCEPT_DECLARE(exception::StateTransition,
00101 sentinelException, msg );
00102 this->post_event( Fail(sentinelException) );
00103 }
00104 catch(...)
00105 {
00106 msg += ": unknown exception";
00107 XCEPT_DECLARE(exception::StateTransition,
00108 sentinelException, msg );
00109 this->post_event( Fail(sentinelException) );
00110 }
00111 };
00112
00113 void safeExitAction()
00114 {
00115 std::string msg = "Failed to leave " + stateName_ + " state";
00116 try
00117 {
00118 exitAction();
00119 }
00120 catch( xcept::Exception& e )
00121 {
00122 XCEPT_DECLARE_NESTED(exception::StateTransition,
00123 sentinelException, msg, e );
00124 this->post_event( Fail(sentinelException) );
00125 }
00126 catch( std::exception& e )
00127 {
00128 msg += ": ";
00129 msg += e.what();
00130 XCEPT_DECLARE(exception::StateTransition,
00131 sentinelException, msg );
00132 this->post_event( Fail(sentinelException) );
00133 }
00134 catch(...)
00135 {
00136 msg += ": unknown exception";
00137 XCEPT_DECLARE(exception::StateTransition,
00138 sentinelException, msg );
00139 this->post_event( Fail(sentinelException) );
00140 }
00141 };
00142
00143 };
00144
00145
00147
00149
00153 class Failed: public State<Failed,StateMachine>
00154 {
00155
00156 public:
00157
00158 typedef boost::mpl::list<
00159 boost::statechart::transition<Fail,Failed>
00160 > reactions;
00161
00162 Failed(my_context c) : my_state("Failed", c)
00163 { safeEntryAction(); }
00164 virtual ~Failed()
00165 { safeExitAction(); }
00166
00167 };
00168
00172 class AllOk: public State<AllOk,StateMachine,Constructed>
00173 {
00174
00175 public:
00176
00177 typedef boost::mpl::list<
00178 boost::statechart::transition<Fail,Failed,StateMachine,&StateMachine::failEvent>
00179 > reactions;
00180
00181 AllOk(my_context c) : my_state("AllOk", c)
00182 { safeEntryAction(); }
00183 virtual ~AllOk()
00184 { safeExitAction(); }
00185
00186 };
00187
00188
00192 class Constructed: public State<Constructed,AllOk>
00193 {
00194
00195 public:
00196
00197 typedef boost::mpl::list<
00198 boost::statechart::transition<Configure,Configuring>
00199 > reactions;
00200
00201 Constructed(my_context c) : my_state("Constructed", c)
00202 { safeEntryAction(); }
00203 virtual ~Constructed()
00204 { safeExitAction(); }
00205
00206 };
00207
00208
00212 class Halted: public State<Halted,AllOk>
00213 {
00214
00215 public:
00216
00217 typedef boost::mpl::list<
00218 boost::statechart::transition<Configure,Configuring>
00219 > reactions;
00220
00221 Halted(my_context c) : my_state("Halted", c)
00222 { safeEntryAction(); }
00223 virtual ~Halted()
00224 { safeExitAction(); }
00225
00226 virtual void entryAction()
00227 { outermost_context().setExternallyVisibleStateName("Halted"); }
00228
00229 };
00230
00231
00235 class Configuring: public State<Configuring,AllOk>
00236 {
00237
00238 public:
00239
00240 typedef boost::mpl::list<
00241 boost::statechart::transition<ConfiguringDone,Ready>
00242 > reactions;
00243
00244 Configuring(my_context c) : my_state("Configuring", c)
00245 { safeEntryAction(); }
00246 virtual ~Configuring()
00247 { safeExitAction(); }
00248
00249 virtual void entryAction();
00250 virtual void exitAction();
00251 void activity();
00252
00253 private:
00254 boost::scoped_ptr<boost::thread> configuringThread_;
00255
00256 };
00257
00258
00262 class Ready: public State<Ready,AllOk>
00263 {
00264
00265 public:
00266
00267 typedef boost::mpl::list<
00268 boost::statechart::transition<Enable,Enabled>,
00269 boost::statechart::transition<Halt,Halted>
00270 > reactions;
00271
00272 Ready(my_context c) : my_state("Ready", c)
00273 { safeEntryAction(); }
00274 virtual ~Ready()
00275 { safeExitAction(); }
00276
00277 virtual void entryAction()
00278 { outermost_context().setExternallyVisibleStateName("Ready"); }
00279
00280 };
00281
00282
00286 class Enabled: public State<Enabled,AllOk,Starting>
00287 {
00288
00289 public:
00290
00291 typedef boost::mpl::list<
00292 boost::statechart::transition<Stop,Stopping>,
00293 boost::statechart::transition<Halt,Halting>
00294 > reactions;
00295
00296 Enabled(my_context c) : my_state("Enabled", c)
00297 { safeEntryAction(); }
00298 virtual ~Enabled()
00299 { safeExitAction(); }
00300
00301
00302
00303
00304 };
00305
00306
00310 class Stopping: public State<Stopping,AllOk>
00311 {
00312
00313 public:
00314
00315 typedef boost::mpl::list<
00316 boost::statechart::transition<StoppingDone,Ready>
00317 > reactions;
00318
00319 Stopping(my_context c) : my_state("Stopping", c)
00320 { safeEntryAction(); }
00321 virtual ~Stopping()
00322 { safeExitAction(); }
00323
00324 virtual void entryAction();
00325 virtual void exitAction();
00326 void activity();
00327
00328 private:
00329 boost::scoped_ptr<boost::thread> stoppingThread_;
00330
00331 };
00332
00333
00337 class Halting: public State<Halting,AllOk>
00338 {
00339
00340 public:
00341
00342 typedef boost::mpl::list<
00343 boost::statechart::transition<HaltingDone,Halted>
00344 > reactions;
00345
00346 Halting(my_context c) : my_state("Halting", c)
00347 { safeEntryAction(); }
00348 virtual ~Halting()
00349 { safeExitAction(); }
00350
00351 virtual void entryAction();
00352 virtual void exitAction();
00353 void activity();
00354
00355 private:
00356 boost::scoped_ptr<boost::thread> haltingThread_;
00357
00358 };
00359
00360
00364 class Starting: public State<Starting,Enabled>
00365 {
00366
00367 public:
00368
00369 typedef boost::mpl::list<
00370 boost::statechart::transition<StartingDone,Running>
00371 > reactions;
00372
00373 Starting(my_context c) : my_state("Starting", c)
00374 { safeEntryAction(); }
00375 virtual ~Starting()
00376 { safeExitAction(); }
00377
00378 virtual void entryAction();
00379 virtual void exitAction();
00380 void activity();
00381
00382 private:
00383 boost::scoped_ptr<boost::thread> startingThread_;
00384
00385 };
00386
00387
00391 class Running: public State<Running,Enabled>
00392 {
00393
00394 public:
00395
00396 Running(my_context c) : my_state("Running", c)
00397 { safeEntryAction(); }
00398 virtual ~Running()
00399 { safeExitAction(); }
00400
00401 virtual void entryAction()
00402 { outermost_context().setExternallyVisibleStateName("Enabled"); }
00403
00404 };
00405
00406
00407 }
00408
00409 #endif //SMProxyServer_States_h
00410
00411