Lely core libraries 2.3.4
sigset.hpp
Go to the documentation of this file.
1
24#ifndef LELY_IO2_SIGSET_HPP_
25#define LELY_IO2_SIGSET_HPP_
26
27#include <lely/ev/future.hpp>
28#include <lely/io2/dev.hpp>
29#include <lely/io2/sigset.h>
30
31#include <utility>
32
33namespace lely {
34namespace io {
35
36namespace detail {
37
38template <class F>
40 public:
43 exec,
44 [](ev_task* task) noexcept {
45 auto wait = io_sigset_wait_from_task(task);
46 auto signo = wait->signo;
47 auto self = static_cast<SignalSetWaitWrapper*>(wait);
48 compat::invoke(::std::move(self->func_), signo);
49 delete self;
50 }),
51 func_(::std::forward<F>(f)) {}
52
54
55 SignalSetWaitWrapper& operator=(const SignalSetWaitWrapper&) = delete;
56
57 private:
58 typename ::std::decay<F>::type func_;
59};
60
61} // namespace detail
62
68template <class F>
69inline typename ::std::enable_if<compat::is_invocable<F, int>::value,
72 return new detail::SignalSetWaitWrapper<F>(exec, ::std::forward<F>(f));
73}
74
81 public:
82 using Signature = void(int);
83
85 template <class F>
89 [](ev_task* task) noexcept {
90 auto wait = io_sigset_wait_from_task(task);
91 auto self = static_cast<SignalSetWait*>(wait);
92 if (self->func_) {
93 auto signo = wait->signo;
94 self->func_(signo);
95 }
96 }),
97 func_(::std::forward<F>(f)) {}
98
100 template <class F>
101 explicit SignalSetWait(F&& f)
102 : SignalSetWait(nullptr, ::std::forward<F>(f)) {}
103
104 SignalSetWait(const SignalSetWait&) = delete;
105
106 SignalSetWait& operator=(const SignalSetWait&) = delete;
107
108 operator ev_task&() & noexcept { return task; }
109
112 get_executor() const noexcept {
113 return ev::Executor(task.exec);
114 }
115
116 private:
117 ::std::function<Signature> func_;
118};
119
124class SignalSetBase : public Device {
125 public:
126 using Device::operator io_dev_t*;
127
128 explicit SignalSetBase(io_sigset_t* sigset_) noexcept
129 : Device(sigset_ ? io_sigset_get_dev(sigset_) : nullptr),
130 sigset(sigset_) {}
131
132 operator io_sigset_t*() const noexcept { return sigset; }
133
135 void
136 clear(::std::error_code& ec) noexcept {
137 int errsv = get_errc();
138 set_errc(0);
139 if (!io_sigset_clear(*this))
140 ec.clear();
141 else
143 set_errc(errsv);
144 }
145
147 void
149 ::std::error_code ec;
150 clear(ec);
151 if (ec) throw ::std::system_error(ec, "clear");
152 }
153
155 void
156 insert(int signo, ::std::error_code& ec) noexcept {
157 int errsv = get_errc();
158 set_errc(0);
159 if (!io_sigset_insert(*this, signo))
160 ec.clear();
161 else
163 set_errc(errsv);
164 }
165
167 void
168 insert(int signo) {
169 ::std::error_code ec;
170 insert(signo, ec);
171 if (ec) throw ::std::system_error(ec, "insert");
172 }
173
175 void
176 remove(int signo, ::std::error_code& ec) noexcept {
177 int errsv = get_errc();
178 set_errc(0);
179 if (!io_sigset_remove(*this, signo))
180 ec.clear();
181 else
183 set_errc(errsv);
184 }
185
187 void
188 remove(int signo) {
189 ::std::error_code ec;
190 remove(signo, ec);
191 if (ec) throw ::std::system_error(ec, "remove");
192 }
193
195 void
196 submit_wait(io_sigset_wait& wait) noexcept {
197 io_sigset_submit_wait(*this, &wait);
198 }
199
201 template <class F>
202 void
203 submit_wait(ev_exec_t* exec, F&& f) {
204 submit_wait(*make_signal_set_wait_wrapper(exec, ::std::forward<F>(f)));
205 }
206
208 template <class F>
209 typename ::std::enable_if<!::std::is_base_of<
210 io_sigset_wait, typename ::std::decay<F>::type>::value>::type
211 submit_wait(F&& f) {
212 submit_wait(nullptr, ::std::forward<F>(f));
213 }
214
217 async_wait(ev_exec_t* exec, struct io_sigset_wait** pwait = nullptr) {
218 auto future = io_sigset_async_wait(*this, exec, pwait);
219 if (!future) util::throw_errc("async_wait");
220 return ev::Future<int, void>(future);
221 }
222
225 async_wait(struct io_sigset_wait** pwait = nullptr) {
226 return async_wait(nullptr, pwait);
227 }
228
229 protected:
230 io_sigset_t* sigset{nullptr};
231};
232
233} // namespace io
234} // namespace lely
235
236#endif // !LELY_IO2_SIGSET_HPP_
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition: exec.hpp:38
A future.
Definition: future.hpp:384
An abstract I/O device. This class is a wrapper around #io_dev_t*.
Definition: dev.hpp:35
A reference to an abstract signal handler.
Definition: sigset.hpp:124
void submit_wait(io_sigset_wait &wait) noexcept
Definition: sigset.hpp:196
typename::std::enable_if<!::std::is_base_of< io_sigset_wait, typename::std::decay< F >::type >::value >::type submit_wait(F &&f)
Definition: sigset.hpp:211
void insert(int signo)
Definition: sigset.hpp:168
void clear(::std::error_code &ec) noexcept
Definition: sigset.hpp:136
void remove(int signo, ::std::error_code &ec) noexcept
Definition: sigset.hpp:176
void insert(int signo, ::std::error_code &ec) noexcept
Definition: sigset.hpp:156
ev::Future< int, void > async_wait(struct io_sigset_wait **pwait=nullptr)
Definition: sigset.hpp:225
void submit_wait(ev_exec_t *exec, F &&f)
Definition: sigset.hpp:203
ev::Future< int, void > async_wait(ev_exec_t *exec, struct io_sigset_wait **pwait=nullptr)
Definition: sigset.hpp:217
void remove(int signo)
Definition: sigset.hpp:188
A wait operation suitable for use with a signal handler.
Definition: sigset.hpp:80
SignalSetWait(ev_exec_t *exec, F &&f)
Constructs a wait operation with a completion task.
Definition: sigset.hpp:86
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: sigset.hpp:112
SignalSetWait(F &&f)
Constructs a wait operation with a completion task.
Definition: sigset.hpp:101
int get_errc(void)
Returns the last (thread-specific) native error code set by a system call or library function.
Definition: errnum.c:932
void set_errc(int errc)
Sets the current (thread-specific) native error code to errc.
Definition: errnum.c:944
This header file is part of the event library; it contains the C++ interface for the futures and prom...
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
This header file is part of the I/O library; it contains the abstract signal handler interface.
int io_sigset_insert(io_sigset_t *sigset, int signo)
Insert the specified signal number into the set of signals being monitored by a signal handler.
Definition: sigset.h:211
const struct io_sigset_vtbl *const io_sigset_t
An abstract signal handler.
Definition: sigset.h:40
ev_future_t * io_sigset_async_wait(io_sigset_t *sigset, ev_exec_t *exec, struct io_sigset_wait **pwait)
Submits an asynchronous wait operation to a signal handler and creates a future which becomes ready o...
Definition: sigset.c:39
void io_sigset_submit_wait(io_sigset_t *sigset, struct io_sigset_wait *wait)
Submits a wait operation to a signal handler.
Definition: sigset.h:223
int io_sigset_remove(io_sigset_t *sigset, int signo)
Removes the specified signal number from the set of signals being monitored by a signal handler.
Definition: sigset.h:217
int io_sigset_clear(io_sigset_t *sigset)
Clears the set of signals being monitored by a signal handler.
Definition: sigset.h:205
#define IO_SIGSET_WAIT_INIT(exec, func)
The static initializer for io_sigset_wait.
Definition: sigset.h:54
struct io_sigset_wait * io_sigset_wait_from_task(struct ev_task *task)
Obtains a pointer to a signal wait operation from a pointer to its completion task.
Definition: sigset.c:62
io_dev_t * io_sigset_get_dev(const io_sigset_t *sigset)
Returns a pointer to the abstract I/O device representing the signal handler.
Definition: sigset.h:199
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
Definition: dev.h:35
This header file is part of the I/O library; it contains the C++ interface for the abstract I/O devic...
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
STL namespace.
typename::std::enable_if< compat::is_invocable< F, int >::value, detail::SignalSetWaitWrapper< F > * >::type make_signal_set_wait_wrapper(ev_exec_t *exec, F &&f)
Creates a wait operation with a completion task.
Definition: sigset.hpp:71
An executable task.
Definition: task.h:41
A wait operation suitable for use with a signal handler.
Definition: sigset.h:43
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the wait operation.
Definition: sigset.h:48
int signo
The signal number, or 0 if the wait operation was canceled.
Definition: sigset.h:50