Lely core libraries  2.3.4
fiber_driver.cpp
Go to the documentation of this file.
1 
25 #include "coapp.hpp"
26 
27 #if !LELY_NO_COAPP_MASTER
28 
30 
31 #include <cassert>
32 
33 namespace lely {
34 
35 namespace canopen {
36 
37 namespace detail {
38 
39 FiberDriverBase::FiberDriverBase(ev_exec_t* exec_)
40 #if !_WIN32 && _POSIX_MAPPED_FILES
41  : thrd(ev::FiberFlag::SAVE_ERROR | ev::FiberFlag::GUARD_STACK),
42 #else
43  : thrd(ev::FiberFlag::SAVE_ERROR),
44 #endif
45  exec(exec_),
46  strand(exec) {
47 }
48 
49 } // namespace detail
50 
51 FiberDriver::FiberDriver(ev_exec_t* exec, AsyncMaster& master, uint8_t id)
52  : FiberDriverBase(exec ? exec
53  : static_cast<ev_exec_t*>(master.GetExecutor())),
54  BasicDriver(FiberDriverBase::exec, master, id) {}
55 
56 void
57 FiberDriver::Wait(SdoFuture<void> f, ::std::error_code& ec) {
58  fiber_await(f);
59  try {
60  f.get().value();
61  } catch (const ::std::system_error& e) {
62  ec = e.code();
63  } catch (const ev::future_not_ready& e) {
64  ec = ::std::make_error_code(::std::errc::operation_canceled);
65  }
66 }
67 
68 void
69 FiberDriver::USleep(uint_least64_t usec) {
70  ::std::error_code ec;
71  USleep(usec, ec);
72  if (ec) throw ::std::system_error(ec, "USleep");
73 }
74 
75 void
76 FiberDriver::USleep(uint_least64_t usec, ::std::error_code& ec) {
77  io_tqueue_wait* wait = nullptr;
78  auto f = master.AsyncWait(::std::chrono::microseconds(usec), &wait);
79  assert(wait);
80  Wait(f, ec);
81  if (!f.is_ready()) master.CancelWait(*wait);
82 }
83 
84 } // namespace canopen
85 
86 } // namespace lely
87 
88 #endif // !LELY_NO_COAPP_MASTER
An asynchronous CANopen master.
Definition: master.hpp:1957
The base class for drivers for remote CANopen nodes.
Definition: driver.hpp:279
BasicMaster & master
A reference to the master with which this driver is registered.
Definition: driver.hpp:1097
T Wait(SdoFuture< T > f)
Waits for the specified future to become ready by suspending the calling fiber.
FiberDriver(ev_exec_t *exec, AsyncMaster &master, uint8_t id)
Creates a new CANopen driver and its associated fiber executor.
void USleep(uint_least64_t usec)
Suspends the calling fiber for usec microseconds.
ev::Future< void, ::std::exception_ptr > AsyncWait(ev_exec_t *exec, const time_point &t, io_tqueue_wait **pwait=nullptr)
Submits an asynchronous wait operation and creates a future which becomes ready once the wait operati...
Definition: node.cpp:185
bool CancelWait(io_tqueue_wait &wait) noexcept
Cancels the specified wait operation if it is pending.
Definition: node.cpp:203
A future.
Definition: future.hpp:384
The exception thrown when retrieving the result of a future which is not ready or does not contain a ...
Definition: future.hpp:45
This is the internal header file of the C++ CANopen application library.
This header file is part of the C++ CANopen application library; it contains the declarations for the...
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
A wait operation suitable for use with a timer queue.
Definition: tqueue.h:36