include/boost/corosio/io/io_signal_set.hpp

100.0% Lines (13 / 13) 100.0% Functions (7 / 7)
io_signal_set.hpp
f(x) Functions (7)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_IO_IO_SIGNAL_SET_HPP
11 #define BOOST_COROSIO_IO_IO_SIGNAL_SET_HPP
12
13 #include <boost/corosio/detail/config.hpp>
14 #include <boost/corosio/detail/op_base.hpp>
15 #include <boost/corosio/io/io_object.hpp>
16 #include <boost/capy/io_result.hpp>
17 #include <boost/capy/error.hpp>
18 #include <boost/capy/ex/executor_ref.hpp>
19 #include <boost/capy/ex/io_env.hpp>
20
21 #include <coroutine>
22 #include <stop_token>
23 #include <system_error>
24
25 namespace boost::corosio {
26
27 /** Abstract base for asynchronous signal sets.
28
29 Provides the common signal set interface: `wait` and `cancel`.
30 Concrete classes like @ref signal_set add signal registration
31 (add, remove, clear) and platform-specific flags.
32
33 @par Thread Safety
34 Distinct objects: Safe.
35 Shared objects: Unsafe.
36
37 @see signal_set, io_object
38 */
39 class BOOST_COROSIO_DECL io_signal_set : public io_object
40 {
41 struct wait_awaitable : detail::value_op_base<wait_awaitable, int>
42 {
43 io_signal_set& s_;
44
45 327x explicit wait_awaitable(io_signal_set& s) noexcept : s_(s) {}
46
47 std::coroutine_handle<>
48 325x dispatch(std::coroutine_handle<> h, capy::executor_ref ex) const
49 {
50 325x return s_.get().wait(h, ex, token_, &ec_, &value_);
51 }
52 };
53
54 public:
55 /** Define backend hooks for signal set wait and cancel.
56
57 Platform backends derive from this to implement
58 signal delivery notification.
59 */
60 struct implementation : io_object::implementation
61 {
62 /** Initiate an asynchronous wait for a signal.
63
64 @param h Coroutine handle to resume on completion.
65 @param ex Executor for dispatching the completion.
66 @param token Stop token for cancellation.
67 @param ec Output error code.
68 @param signo Output signal number.
69
70 @return Coroutine handle to resume immediately.
71 */
72 virtual std::coroutine_handle<> wait(
73 std::coroutine_handle<> h,
74 capy::executor_ref ex,
75 std::stop_token token,
76 std::error_code* ec,
77 int* signo) = 0;
78
79 /** Cancel all pending wait operations.
80
81 Cancelled waiters complete with an error that
82 compares equal to `capy::cond::canceled`.
83 */
84 virtual void cancel() noexcept = 0;
85 };
86
87 /** Cancel all operations associated with the signal set.
88
89 Forces the completion of any pending asynchronous wait
90 operations. Each cancelled operation completes with an error
91 code that compares equal to `capy::cond::canceled`.
92
93 Cancellation does not alter the set of registered signals.
94 */
95 15x void cancel() noexcept
96 {
97 15x do_cancel();
98 15x }
99
100 /** Wait for a signal to be delivered.
101
102 The operation supports cancellation via `std::stop_token` through
103 the affine awaitable protocol. If the associated stop token is
104 triggered, the operation completes immediately with an error
105 that compares equal to `capy::cond::canceled`.
106
107 This signal set must outlive the returned awaitable.
108
109 @return An awaitable that completes with `io_result<int>`.
110 Returns the signal number when a signal is delivered,
111 or an error code on failure.
112 */
113 327x [[nodiscard]] auto wait()
114 {
115 327x return wait_awaitable(*this);
116 }
117
118 protected:
119 /** Dispatch cancel to the concrete implementation. */
120 virtual void do_cancel() noexcept = 0;
121
122 177x explicit io_signal_set(handle h) noexcept : io_object(std::move(h)) {}
123
124 /// Move construct.
125 2x io_signal_set(io_signal_set&& other) noexcept : io_object(std::move(other))
126 {
127 2x }
128
129 /// Move assign.
130 io_signal_set& operator=(io_signal_set&& other) noexcept
131 {
132 if (this != &other)
133 h_ = std::move(other.h_);
134 return *this;
135 }
136
137 io_signal_set(io_signal_set const&) = delete;
138 io_signal_set& operator=(io_signal_set const&) = delete;
139
140 private:
141 325x implementation& get() const noexcept
142 {
143 325x return *static_cast<implementation*>(h_.get());
144 }
145 };
146
147 } // namespace boost::corosio
148
149 #endif
150