Lely core libraries  2.3.4
co_can.hpp
Go to the documentation of this file.
1 
25 #ifndef LELY_IO2_CO_CAN_HPP_
26 #define LELY_IO2_CO_CAN_HPP_
27 
28 #include <lely/io2/can.hpp>
29 #include <lely/util/coroutine.hpp>
30 
31 namespace lely {
32 namespace io {
33 
39  public:
41  explicit CoCanChannelRead(can_msg* msg, can_err* err = nullptr,
42  ::std::chrono::nanoseconds* dp = nullptr,
43  ev_exec_t* exec = nullptr) noexcept
45  msg, err, dp ? &ts_ : nullptr, exec,
46  [](ev_task* task) noexcept {
47  auto read = io_can_chan_read_from_task(task);
48  auto result = read->r.result;
49  ::std::error_code ec;
50  if (result == -1) ec = util::make_error_code(read->r.errc);
51  auto self = static_cast<CoCanChannelRead*>(read);
52  if (self->dp_) *self->dp_ = util::from_timespec(self->ts_);
53  (*self)(result, ec);
54  }),
55  dp_(dp) {}
56 
57  virtual ~CoCanChannelRead() = default;
58 
59  operator ev_task&() & noexcept { return task; }
60 
62  ev::Executor
63  get_executor() const noexcept {
64  return ev::Executor(task.exec);
65  }
66 
75  virtual void operator()(int result, ::std::error_code ec) noexcept = 0;
76 
77  private:
78  timespec ts_{0, 0};
79  ::std::chrono::nanoseconds* dp_{nullptr};
80 };
81 
87  public:
89  CoCanChannelWrite(const can_msg* msg, ev_exec_t* exec = nullptr) noexcept
91  IO_CAN_CHAN_WRITE_INIT(msg, exec, [](ev_task* task) noexcept {
92  auto write = io_can_chan_write_from_task(task);
93  ::std::error_code ec = util::make_error_code(write->errc);
94  auto self = static_cast<CoCanChannelWrite*>(write);
95  (*self)(ec);
96  }) {}
97 
98  virtual ~CoCanChannelWrite() = default;
99 
100  operator ev_task&() & noexcept { return task; }
101 
103  ev::Executor
104  get_executor() const noexcept {
105  return ev::Executor(task.exec);
106  }
107 
114  virtual void operator()(::std::error_code ec) noexcept = 0;
115 };
116 
117 } // namespace io
118 } // namespace lely
119 
120 #endif // !LELY_IO2_CO_CAN_HPP_
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition: exec.hpp:38
A CAN channel read operation with a stackless coroutine as the completion task.
Definition: co_can.hpp:38
virtual void operator()(int result, ::std::error_code ec) noexcept=0
The coroutine to be executed once the read operation completes (or is canceled).
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: co_can.hpp:63
CoCanChannelRead(can_msg *msg, can_err *err=nullptr, ::std::chrono::nanoseconds *dp=nullptr, ev_exec_t *exec=nullptr) noexcept
Constructs a read operation.
Definition: co_can.hpp:41
A CAN channel write operation with a stackless coroutine as the completion task.
Definition: co_can.hpp:86
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: co_can.hpp:104
CoCanChannelWrite(const can_msg *msg, ev_exec_t *exec=nullptr) noexcept
Constructs a write operation.
Definition: co_can.hpp:89
virtual void operator()(::std::error_code ec) noexcept=0
The coroutine to be executed once the write operation completes (or is canceled).
The parent class for function objects used as stackless coroutines.
Definition: coroutine.hpp:48
This header file is part of the utilities library; it contains the C++ implementation of stackless co...
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
struct io_can_chan_write * io_can_chan_write_from_task(struct ev_task *task)
Obtains a pointer to a CAN channel write operation from a pointer to its completion task.
Definition: can.c:99
struct io_can_chan_read * io_can_chan_read_from_task(struct ev_task *task)
Obtains a pointer to a CAN channel read operation from a pointer to its completion task.
Definition: can.c:93
#define IO_CAN_CHAN_WRITE_INIT(msg, exec, func)
The static initializer for io_can_chan_write.
Definition: can.h:130
#define IO_CAN_CHAN_READ_INIT(msg, err, tp, exec, func)
The static initializer for io_can_chan_read.
Definition: can.h:104
This header file is part of the I/O library; it contains the C++ interface for the abstract CAN bus.
::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 CAN error frame.
Definition: err.h:28
A CAN or CAN FD format frame.
Definition: msg.h:87
An executable task.
Definition: task.h:41
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
Definition: task.h:43
A CAN channel read operation.
Definition: can.h:74
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
Definition: can.h:98
struct can_msg * msg
The address at which to store the CAN frame.
Definition: can.h:80
struct can_err * err
The address at which to store the CAN error frame.
Definition: can.h:86
A CAN channel write operation.
Definition: can.h:110
const struct can_msg * msg
A pointer to the CAN frame to be written.
Definition: can.h:116
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the write operation.
Definition: can.h:121