source: trunk/FACT++/src/StateMachineAsio.h@ 16737

Last change on this file since 16737 was 16736, checked in by tbretz, 12 years ago
Of course we cannot call Execute of the base class, but have to make sure the overwritten function is called.
File size: 2.7 KB
Line 
1#ifndef FACT_StateMachineAsio
2#define FACT_StateMachineAsio
3
4#include <boost/asio.hpp>
5#include <boost/bind.hpp>
6
7template <class T>
8class StateMachineAsio : public T, public boost::asio::io_service, public boost::asio::io_service::work
9{
10 boost::asio::deadline_timer fTrigger;
11
12 void HandleTrigger(const boost::system::error_code &error)
13 {
14 // 125: Operation canceled (bs::error_code(125, bs::system_category))
15 if (error && error!=boost::asio::error::basic_errors::operation_aborted)
16 return;
17
18 fTrigger.expires_from_now(boost::posix_time::microseconds(10000));
19 fTrigger.async_wait(boost::bind(&StateMachineAsio::HandleTrigger,
20 this, boost::asio::placeholders::error));
21
22 if (!HandleNewState(Execute(), 0, "by HandleTrigger()"))
23 Stop(-1);
24 }
25
26 void Handler()
27 {
28 const auto ptr = T::PopEvent();
29 if (!T::HandleEvent(*ptr))
30 Stop(-1);
31 }
32
33 void PushEvent(Event *cmd)
34 {
35 T::PushEvent(cmd);
36 dispatch(boost::bind(&StateMachineAsio::Handler, this));
37 }
38
39 int Execute()=0;
40
41 int Run(bool)
42 {
43 fTrigger.expires_from_now(boost::posix_time::microseconds(0));
44 fTrigger.async_wait(boost::bind(&StateMachineAsio::HandleTrigger,
45 this, boost::asio::placeholders::error));
46
47 T::SetCurrentState(StateMachineImp::kSM_Ready, "by Run()");
48
49 T::fRunning = true;
50
51 while (run_one())
52 {
53 if (!HandleNewState(Execute(), 0, "by Run()"))
54 Stop(-1);
55 }
56 reset();
57
58 T::fRunning = false;
59
60 if (T::fExitRequested==-1)
61 {
62 T::Fatal("Fatal Error occured... shutting down.");
63 return -1;
64 }
65
66 T::SetCurrentState(StateMachineImp::kSM_NotReady, "due to return from Run().");
67
68 const int exitcode = T::fExitRequested-1;
69 T::fExitRequested = 0;
70 return exitcode;
71 }
72
73
74public:
75 StateMachineAsio(std::ostream &out, const std::string &server) :
76 T(out, server), boost::asio::io_service::work(static_cast<boost::asio::io_service&>(*this)),
77 fTrigger(static_cast<boost::asio::io_service&>(*this))
78 {
79 // ba::io_service::work is a kind of keep_alive for the loop.
80 // It prevents the io_service to go to stopped state, which
81 // would prevent any consecutive calls to run()
82 // or poll() to do nothing. reset() could also revoke to the
83 // previous state but this might introduce some overhead of
84 // deletion and creation of threads and more.
85 }
86
87 void Stop(int code=0)
88 {
89 T::Stop(code);
90 stop();
91 }
92};
93
94#endif
Note: See TracBrowser for help on using the repository browser.