26#if !LELY_NO_COAPP_MASTER && !LELY_NO_THREADS
58 ::std::atomic_flag shutdown{
false};
65 ::std::atomic_flag joined{
false};
78 :
BasicDriver(strand.get_inner_executor(), master, id),
79 impl_(
new Impl_(this, master.GetContext())) {}
90 return impl_->stopped.get_future();
98 }
catch (const ::std::system_error&
e) {
101 ec = ::std::make_error_code(::std::errc::operation_canceled);
107 ::std::error_code ec;
109 if (ec) throw ::std::system_error(ec,
"USleep");
127 thread(&Impl_::Start, this)
133 [](
void* arg)
noexcept {
138 util::throw_errc(
"thrd_create");
143LoopDriver::Impl_::~Impl_() {
149LoopDriver::Impl_::Start() {
150 auto& loop = self->GetLoop();
151 auto exec = self->GetExecutor();
161 self->master.Erase(*self);
173LoopDriver::Impl_::Shutdown() {
174 if (!shutdown.test_and_set()) {
176 self->master.Erase(*self);
178 self->GetLoop().stop();
183LoopDriver::Impl_::Join() {
184 if (!joined.test_and_set()) {
An asynchronous CANopen master.
The base class for drivers for remote CANopen nodes.
BasicMaster & master
A reference to the master with which this driver is registered.
A CANopen driver running its own dedicated event loop in a separate thread.
void USleep(uint_least64_t usec)
Runs the event loop for usec microseconds.
T Wait(SdoFuture< T > f)
Waits for the specified future to become ready by running pending tasks on the dedicated event loop o...
void Join()
Stops the dedicated event loop of the driver and waits until the thread running the event loop finish...
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...
ev::Loop & GetLoop() noexcept
Returns a reference to the dedicated event loop of the driver.
~LoopDriver()
Stops the event loop and terminates the thread in which it was running before destroying the driver.
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...
bool CancelWait(io_tqueue_wait &wait) noexcept
Cancels the specified wait operation if it is pending.
::std::size_t wait(ev_future_t *future)
The exception thrown when retrieving the result of a future which is not ready or does not contain a ...
A refence to an I/O context. This class is a wrapper around #io_ctx_t*.
void remove(io_svc &svc) noexcept
This is the internal header file of the C++ CANopen application library.
#define IO_SVC_INIT(vptr)
The static initializer for io_svc.
This header file is part of the C++ CANopen application library; it contains the declarations for the...
The virtual table of an I/O service.
A wait operation suitable for use with a timer queue.
The internal implementation of lely::canopen::LoopDriver.
This header file is part of the C11 and POSIX compatibility library; it includes <threads....
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
Creates a new thread executing func(arg).
int thrd_join(thrd_t thr, int *res)
Joins the thread identified by thr with the current thread by blocking until the other thread has ter...
@ thrd_success
Indicates that the requested operation succeeded.