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

Last change on this file since 19008 was 18054, checked in by tbretz, 10 years ago
My compiler couldn't resolve the inheritance of HandleNewStae
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 (!T::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 post(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 (!T::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.