Lely core libraries  2.3.4
loop_driver.hpp
Go to the documentation of this file.
1 
22 #ifndef LELY_COAPP_LOOP_DRIVER_HPP_
23 #define LELY_COAPP_LOOP_DRIVER_HPP_
24 
25 #include <lely/coapp/driver.hpp>
26 #include <lely/ev/loop.hpp>
27 #include <lely/ev/strand.hpp>
28 
29 #include <memory>
30 #include <utility>
31 
32 namespace lely {
33 
34 namespace canopen {
35 
36 namespace detail {
37 
43  protected:
44  ev::Loop loop{};
45  ev::Strand strand{loop.get_executor()};
46 };
47 
48 } // namespace detail
49 
52  public:
62  explicit LoopDriver(AsyncMaster& master, uint8_t id);
63 
70  ~LoopDriver();
71 
73  ev::Loop&
74  GetLoop() noexcept {
75  return loop;
76  }
77 
80  GetStrand() const noexcept {
81  return strand;
82  }
83 
94  void Join();
95 
101 
108  template <class F, class... Args>
109  void
110  Defer(F&& f, Args&&... args) {
111  GetStrand().post(::std::forward<F>(f), ::std::forward<Args>(args)...);
112  }
113 
126  template <class T>
127  T
129  GetLoop().wait(f);
130  try {
131  return f.get().value();
132  } catch (const ev::future_not_ready& e) {
133  util::throw_error_code("Wait", ::std::errc::operation_canceled);
134  }
135  }
136 
149  template <class T>
150  typename ::std::enable_if<!::std::is_void<T>::value, T>::type
151  Wait(SdoFuture<T> f, ::std::error_code& ec) {
152  GetLoop().wait(f, ec);
153  try {
154  return f.get().value();
155  } catch (const ::std::system_error& e) {
156  ec = e.code();
157  } catch (const ev::future_not_ready& e) {
158  ec = ::std::make_error_code(::std::errc::operation_canceled);
159  }
160  return T{};
161  }
162 
174  void Wait(SdoFuture<void> f, ::std::error_code& ec);
175 
180  void USleep(uint_least64_t usec);
181 
186  void USleep(uint_least64_t usec, ::std::error_code& ec);
187 
193  template <class T>
194  T
195  RunRead(uint16_t idx, uint8_t subidx) {
196  return Wait(AsyncRead<T>(idx, subidx));
197  }
198 
205  template <class T>
206  T
207  RunRead(uint16_t idx, uint8_t subidx, ::std::error_code& ec) {
208  return Wait(AsyncRead<T>(idx, subidx), ec);
209  }
210 
216  template <class T>
217  T
218  RunRead(uint16_t idx, uint8_t subidx,
219  const ::std::chrono::milliseconds& timeout) {
220  return Wait(AsyncRead<T>(idx, subidx, timeout));
221  }
222 
238  template <class T>
239  T
240  RunRead(uint16_t idx, uint8_t subidx,
241  const ::std::chrono::milliseconds& timeout, ::std::error_code& ec) {
242  return Wait(AsyncRead<T>(idx, subidx, timeout), ec);
243  }
244 
250  template <class T>
251  void
252  RunWrite(uint16_t idx, uint8_t subidx, T&& value) {
253  Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value)));
254  }
255 
262  template <class T>
263  void
264  RunWrite(uint16_t idx, uint8_t subidx, T&& value, ::std::error_code& ec) {
265  Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value)), ec);
266  }
267 
273  template <class T>
274  void
275  RunWrite(uint16_t idx, uint8_t subidx, T&& value,
276  const ::std::chrono::milliseconds& timeout) {
277  Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value), timeout));
278  }
279 
294  template <class T>
295  void
296  RunWrite(uint16_t idx, uint8_t subidx, T&& value,
297  const ::std::chrono::milliseconds& timeout, ::std::error_code& ec) {
298  Wait(AsyncWrite(idx, subidx, ::std::forward<T>(value), timeout), ec);
299  }
300 
301  private:
302  struct Impl_;
303  ::std::unique_ptr<Impl_> impl_;
304 };
305 
306 } // namespace canopen
307 
308 } // namespace lely
309 
310 #endif // LELY_COAPP_LOOP_DRIVER_HPP_
lely::ev::Executor::post
void post(ev_task &task) noexcept
Definition: exec.hpp:75
lely::ev::Loop
A polling event loop.
Definition: loop.hpp:41
lely::canopen::BasicDriver::master
BasicMaster & master
A reference to the master with which this driver is registered.
Definition: driver.hpp:1097
lely::canopen::BasicDriver
The base class for drivers for remote CANopen nodes.
Definition: driver.hpp:278
lely::canopen::LoopDriver::AsyncStoppped
ev::Future< void, void > AsyncStoppped() noexcept
Returns a future which becomes ready once the dedicated event loop of the driver is stopped and the t...
Definition: loop_driver.cpp:89
lely::canopen::AsyncMaster
An asynchronous CANopen master.
Definition: master.hpp:1957
loop.hpp
lely::canopen::LoopDriver::RunWrite
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous write (SDO download) operation and runs the event loop until the operation is ...
Definition: loop_driver.hpp:296
lely::ev::Strand
A strand executor.
Definition: strand.hpp:37
lely::canopen::BasicDriver::AsyncWrite
SdoFuture< void > AsyncWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to AsyncWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseconds& ...
Definition: driver.hpp:937
lely::ev::Loop::get_executor
Executor get_executor() const noexcept
Definition: loop.hpp:80
lely::canopen::LoopDriver
A CANopen driver running its own dedicated event loop in a separate thread.
Definition: loop_driver.hpp:51
lely::canopen::LoopDriver::RunWrite
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, ::std::error_code &ec)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseconds& ti...
Definition: loop_driver.hpp:264
lely::canopen::LoopDriver::RunRead
T RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds &timeout, ::std::error_code &ec)
Queues an asynchronous read (SDO upload) operation and runs the event loop until the operation is com...
Definition: loop_driver.hpp:240
lely::canopen::LoopDriver::RunWrite
void RunWrite(uint16_t idx, uint8_t subidx, T &&value)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, ::std::error_code& ec),...
Definition: loop_driver.hpp:252
lely::canopen::LoopDriver::Wait
typename ::std::enable_if<!::std::is_void< T >::value, T >::type Wait(SdoFuture< T > f, ::std::error_code &ec)
Waits for the specified future to become ready by running pending tasks on the dedicated event loop o...
Definition: loop_driver.hpp:151
lely::canopen::LoopDriver::RunRead
T RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds &timeout)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout,...
Definition: loop_driver.hpp:218
lely::canopen::LoopDriver::Wait
T Wait(SdoFuture< T > f)
Waits for the specified future to become ready by running pending tasks on the dedicated event loop o...
Definition: loop_driver.hpp:128
lely::ev::Executor
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition: exec.hpp:38
lely::ev::Future
A future.
Definition: future.hpp:50
lely::canopen::LoopDriver::RunRead
T RunRead(uint16_t idx, uint8_t subidx, ::std::error_code &ec)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, const ::std::chrono::milliseconds& timeout,...
Definition: loop_driver.hpp:207
lely::canopen::detail::LoopDriverBase
A base class for lely::canopen::LoopDriver, containing an event loop and the associated executor.
Definition: loop_driver.hpp:42
lely::canopen::LoopDriver::GetStrand
ev::Executor GetStrand() const noexcept
Returns the strand executor associated with the event loop of the driver.
Definition: loop_driver.hpp:80
driver.hpp
strand.hpp
lely::canopen::LoopDriver::RunWrite
void RunWrite(uint16_t idx, uint8_t subidx, T &&value, const ::std::chrono::milliseconds &timeout)
Equivalent to RunWrite(uint16_t idx, uint8_t subidx, T&& value, const ::std::chrono::milliseconds& ti...
Definition: loop_driver.hpp:275
lely::ev::future_not_ready
The exception thrown when retrieving the result of a future which is not ready or does not contain a ...
Definition: future.hpp:45
lely::canopen::LoopDriver::Defer
void Defer(F &&f, Args &&... args)
Schedules the specified Callable object for execution by the event loop for this driver.
Definition: loop_driver.hpp:110
lely::canopen::LoopDriver::USleep
void USleep(uint_least64_t usec)
Runs the event loop for usec microseconds.
Definition: loop_driver.cpp:106
lely::ev::Loop::wait
::std::size_t wait(ev_future_t *future)
Definition: loop.hpp:104
lely::canopen::LoopDriver::GetLoop
ev::Loop & GetLoop() noexcept
Returns a reference to the dedicated event loop of the driver.
Definition: loop_driver.hpp:74
lely::canopen::make_error_code
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
lely::canopen::LoopDriver::~LoopDriver
~LoopDriver()
Stops the event loop and terminates the thread in which it was running before destroying the driver.
lely::canopen::LoopDriver::Join
void Join()
Stops the dedicated event loop of the driver and waits until the thread running the event loop finish...
Definition: loop_driver.cpp:84
lely::canopen::LoopDriver::RunRead
T RunRead(uint16_t idx, uint8_t subidx)
Equivalent to RunRead(uint16_t idx, uint8_t subidx, ::std::error_code& ec), except that it throws lel...
Definition: loop_driver.hpp:195