26 #if !LELY_NO_COAPP_MASTER && !LELY_NO_THREADS 56 ::std::atomic_flag shutdown;
63 ::std::atomic_flag joined;
76 :
BasicDriver(strand.get_inner_executor(), master, id),
77 impl_(new
Impl_(this, master.GetContext())) {}
88 return impl_->stopped.get_future();
96 }
catch (const ::std::system_error& e) {
105 ::std::error_code ec;
107 if (ec) throw ::std::system_error(ec,
"USleep");
113 if (ec == ::std::errc::timed_out) {
115 }
else if (!ec &&
GetLoop().stopped()) {
126 thread(&Impl_::Start,
this)
132 [](
void* arg) noexcept {
137 util::throw_errc(
"thrd_create");
142 LoopDriver::Impl_::~Impl_() {
148 LoopDriver::Impl_::Start() {
149 auto& loop =
self->GetLoop();
150 auto exec =
self->GetExecutor();
160 self->master.Erase(*
self);
172 LoopDriver::Impl_::Shutdown() {
173 if (!shutdown.test_and_set()) {
175 self->master.Erase(*
self);
177 self->GetLoop().stop();
182 LoopDriver::Impl_::Join() {
183 if (!joined.test_and_set()) {
197 #endif // !LELY_NO_COAPP_MASTER && !LELY_NO_THREADS An asynchronous CANopen master.
The base class for drivers for remote CANopen nodes.
A refence to an I/O context. This class is a wrapper around io_ctx_t*.
This is the internal header file of the C++ CANopen application library.
Indicates that the requested operation succeeded.
The exception thrown when retrieving the result of a future which is not ready or does not contain a ...
pthread_t thrd_t
A complete object type that holds an identifier for a thread.
::std::size_t wait(ev_future_t *future)
This header file is part of the C++ CANopen application library; it contains the declarations for the...
This header file is part of the C11 and POSIX compatibility library; it includes <threads.h>, if it exists, and defines any missing functionality.
void USleep(uint_least64_t usec)
Runs the event loop for usec microseconds.
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...
The internal implementation of lely::canopen::LoopDriver.
T Wait(SdoFuture< T > f)
Waits for the specified future to become ready by running pending tasks on the dedicated event loop o...
A CANopen driver running its own dedicated event loop in a separate thread.
~LoopDriver()
Stops the event loop and terminates the thread in which it was running before destroying the driver...
LoopDriver(AsyncMaster &master, uint8_t id)
Creates a new CANopen driver and starts a new event loop in a separate thread to execute event handle...
int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
Creates a new thread executing func(arg).
::std::size_t run_for(const ::std::chrono::duration< Rep, Period > &d)
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...
void Join()
Stops the dedicated event loop of the driver and waits until the thread running the event loop finish...
BasicMaster & master
A reference to the master with which this driver is registered.
The virtual table of an I/O service.
result_type & get()
Returns the result of a ready future.
#define IO_SVC_INIT(vptr)
The static initializer for io_svc.
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
ev::Loop & GetLoop() noexcept
Returns a reference to the dedicated event loop of the driver.