rad  3.0.0
executorActivity.hpp
Go to the documentation of this file.
1 
8 #ifndef RAD_EXECUTOR_ACTIVITY_HPP
9 #define RAD_EXECUTOR_ACTIVITY_HPP
10 #define BOOST_THREAD_PROVIDES_FUTURE
11 
12 #include <string>
13 #include <boost/thread/future.hpp>
14 #include <boost/asio/post.hpp>
15 
16 #include <scxml4cpp/Activity.h>
17 #include <rad/stopToken.hpp>
18 
19 
20 namespace rad {
21 
38 template <class Executor, class Func>
40 public:
41  explicit ExecutorActivity(const std::string& id, Executor ex, Func&& func)
42  : Activity(id), m_executor(std::move(ex)), m_func(std::move(func)), m_done(), m_stop_source() {
43  }
46 
47 
55  void start(scxml4cpp::Context* c) override;
56 
62  void stop(scxml4cpp::Context* c) override;
63 
64  private:
65  Executor m_executor;
66  Func m_func;
67  boost::future<void> m_done;
68  StopSource m_stop_source;
69 };
70 
71 
72 //
73 // Implementation
74 //
75 template <class Executor, class Func>
77  if (m_done.valid()) {
78  // There's already an activity running that needs to be stopped first.
79  return;
80  }
81 
82  // Create a new stop source to guarantee that it was not already stopped.
83  m_stop_source = StopSource();
84 
85  boost::promise<void> p;
86  m_done = p.get_future();
87  boost::asio::post(m_executor, [f = m_func, ex=m_executor, token=m_stop_source.GetToken(), done = std::move(p)]() mutable {
88  RAD_ASSERT(token.StopPossible());
89  std::invoke(f, ex, token);
90  done.set_value();
91  });
92 }
93 
94 template<class Executor, class Func>
95 void
97  if (!m_stop_source.StopPossible()) {
98  // Activity not started
99  return;
100  }
101 
102  // Stop
103  m_stop_source.RequestStop();
104 
105  try {
106  std::cout << "Await stop of activity\n";
107  m_done.get();
108  std::cout << "stop of activity\n";
109  } catch (boost::future_uninitialized const&) {
110  // No activity was running
111  } catch (boost::broken_promise const&) {
112  // Activity finished, but might have crashed
113  } catch (...) {
114  // Unknown error
115  }
116 }
117 
118 } // namespace rad
119 
120 #endif // RAD_EXECUTOR_ACTIVITY_HPP
Executor
boost::asio::io_context::executor_type Executor
Definition: testExecutorActivity.cpp:13
scxml4cpp::Activity
Definition: Activity.h:40
rad::ExecutorActivity::start
void start(scxml4cpp::Context *c) override
Disable assignment operator.
Definition: executorActivity.hpp:76
rad::ExecutorActivity::ExecutorActivity
ExecutorActivity(const ExecutorActivity &)=delete
rad::StopSource
Definition: stopToken.hpp:112
rad::ExecutorActivity::operator=
ExecutorActivity & operator=(const ExecutorActivity &)=delete
Disable copy constructor.
rad
Definition: actionCallback.hpp:21
scxml4cpp::Activity::Activity
Activity(const std::string &id)
Definition: Activity.cpp:32
Func
std::reference_wrapper< MockFunc > Func
Definition: testExecutorActivity.cpp:35
std
Definition: errors.hpp:58
rad::ExecutorActivity
Definition: executorActivity.hpp:39
rad::ExecutorActivity::stop
void stop(scxml4cpp::Context *c) override
Definition: executorActivity.hpp:96
rad::ExecutorActivity::ExecutorActivity
ExecutorActivity(const std::string &id, Executor ex, Func &&func)
Definition: executorActivity.hpp:41
scxml4cpp::Context
Definition: Context.h:44