CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/EventFilter/SMProxyServer/interface/States.h

Go to the documentation of this file.
00001 // $Id: States.h,v 1.2 2011/03/07 15:41:54 mommsen Exp $
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   // Forward declarations of state classes //
00028 
00029   // Outer states:
00030   class Failed;
00031   class AllOk;
00032   // Inner states of AllOk
00033   class Constructed;
00034   class Halted;
00035   class Configuring;
00036   class Ready;
00037   class Enabled;
00038   class Stopping;
00039   class Halting;
00040   // Inner states of Enabled
00041   class Starting;
00042   class Running;
00043 
00044 
00046   // Internal transition events //
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   // Wrapper state template //
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   // State classes //
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     // virtual void entryAction();
00302     // virtual void exitAction();
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 } //namespace smproxy
00408 
00409 #endif //SMProxyServer_States_h
00410 
00411