26#include <lely/aio/detail/timespec.hpp>
44 if (mutex) mutex->
lock();
48 if (mutex) mutex->
unlock();
51 void operator()(::std::error_code ec)
noexcept;
52 void operator()(::std::error_code ec,
int result)
noexcept;
54 int OnNext(
const timespec* tp)
noexcept;
55 int OnSend(
const can_msg* msg)
noexcept;
60 TimerBase::WaitOperation wait_op;
63 CanBusBase::Frame msg CAN_MSG_INIT;
64 CanBusBase::Info info CAN_MSG_INFO_INIT;
67 CanBusBase::ReadOperation read_op;
69 BasicLockable* mutex{
nullptr};
71 unique_c_ptr<CANNet> net;
76 : impl_(new
Impl_(this, timer, bus, mutex)) {}
78IoContext::~IoContext() =
default;
82 return impl_->timer.GetExecutor();
87 return impl_->net.get();
92 net()->setTime(aio::detail::ToTimespec(impl_->timer.GetClock().GetTime()));
95IoContext::Impl_::Impl_(
IoContext* self_, TimerBase& timer_, CanBusBase& bus_,
99 wait_op(::
std::ref(*this)),
101 read_op(&msg, &info, ::
std::ref(*this)),
105 net->setTime(aio::detail::ToTimespec(timer.GetClock().GetTime()));
109 net->setNextFunc<Impl_, &Impl_::OnNext>(
this);
112 net->setSendFunc<Impl_, &Impl_::OnSend>(
this);
115 timer.SubmitWait(wait_op);
118 bus.SubmitRead(read_op);
122IoContext::Impl_::operator()(::std::error_code ec)
noexcept {
124 ::std::lock_guard<Impl_> lock(*
this);
127 timer.SubmitWait(wait_op);
131IoContext::Impl_::operator()(::std::error_code ec,
int result)
noexcept {
133 ::std::lock_guard<Impl_> lock(*
this);
136 }
else if (!result) {
137 if (info.state != state) {
138 ::std::swap(info.state, state);
139 self->OnCanState(
static_cast<CanState
>(state),
140 static_cast<CanState
>(info.state));
142 if (info.error != error) {
144 self->OnCanError(
static_cast<CanError
>(error));
148 bus.SubmitRead(read_op);
152IoContext::Impl_::OnNext(
const timespec* tp)
noexcept {
153 timer.SetTime(TimerBase::time_point(aio::detail::FromTimespec(*tp)));
158IoContext::Impl_::OnSend(
const can_msg* msg)
noexcept {
161 ::std::error_code ec;
162 if (!bus.Write(*msg, ec)) {
An opaque CAN network interface type.
An abstract interface conforming to the BasicLockable concept.
virtual void unlock()=0
Releases the lock held by the execution agent. Throws no exceptions.
virtual void lock()=0
Blocks until a lock can be obtained for the current execution agent (thread, process,...
IoContext(aio::TimerBase &timer, aio::CanBusBase &bus, BasicLockable *mutex=nullptr)
Creates a new I/O context.
void SetTime()
Update the CAN network time.
CANNet * net() const noexcept
Returns a pointer to the internal CAN network interface from <lely/can/net.hpp>.
aio::ExecutorBase GetExecutor() const noexcept
Returns the executor used to process I/O events on the CAN bus.
The type of objects thrown as exceptions to report a system error with an associated error code.
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
This header file is part of the C++ CANopen application library; it contains the I/O context declarat...
Global namespace for the Lely Industries N.V. libraries.
unique_c_ptr< T > make_unique_c(Args &&... args)
Creates an instance of a trivial, standard layout or incomplete C type and wraps it in a lely::unique...
This header file is part of the CAN library; it contains the C++ interface of the CAN network interfa...
This is the internal header file of the C++ CANopen application library.
A CAN or CAN FD format frame.
The internal implementation of the I/O context.
void unlock() override
Releases the lock held by the execution agent. Throws no exceptions.
void lock() override
Blocks until a lock can be obtained for the current execution agent (thread, process,...
A time type with nanosecond resolution.