include/boost/corosio/native/native_signal_set.hpp

100.0% Lines (10 / 10) 100.0% Functions (10 / 10)
native_signal_set.hpp
f(x) Functions (10)
Function Calls Lines Blocks
boost::corosio::native_signal_set<boost::corosio::epoll_t{}>::native_signal_set(boost::capy::execution_context&) :85 2x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::select_t{}>::native_signal_set(boost::capy::execution_context&) :85 2x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::epoll_t{}>::native_signal_set<>(boost::capy::execution_context&, int) :103 2x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::epoll_t{}>::native_signal_set<int>(boost::capy::execution_context&, int, int) :103 1x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::select_t{}>::native_signal_set<>(boost::capy::execution_context&, int) :103 2x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::select_t{}>::native_signal_set<int>(boost::capy::execution_context&, int, int) :103 1x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::epoll_t{}>::native_signal_set<boost::corosio::io_context::executor_type>(boost::corosio::io_context::executor_type const&) :120 1x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::select_t{}>::native_signal_set<boost::corosio::io_context::executor_type>(boost::corosio::io_context::executor_type const&) :120 1x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::epoll_t{}>::native_signal_set<boost::corosio::io_context::executor_type, int>(boost::corosio::io_context::executor_type const&, int, int) :141 1x 100.0% 100.0% boost::corosio::native_signal_set<boost::corosio::select_t{}>::native_signal_set<boost::corosio::io_context::executor_type, int>(boost::corosio::io_context::executor_type const&, int, int) :141 1x 100.0% 100.0%
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Steve Gerbino
3 // Copyright (c) 2026 Michael Vandeberg
4 //
5 // Distributed under the Boost Software License, Version 1.0. (See accompanying
6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 //
8 // Official repository: https://github.com/cppalliance/corosio
9 //
10
11 #ifndef BOOST_COROSIO_NATIVE_NATIVE_SIGNAL_SET_HPP
12 #define BOOST_COROSIO_NATIVE_NATIVE_SIGNAL_SET_HPP
13
14 #include <boost/corosio/signal_set.hpp>
15 #include <boost/corosio/backend.hpp>
16 #include <boost/corosio/detail/op_base.hpp>
17
18 #ifndef BOOST_COROSIO_MRDOCS
19 #if BOOST_COROSIO_HAS_EPOLL || BOOST_COROSIO_HAS_SELECT || \
20 BOOST_COROSIO_HAS_KQUEUE
21 #include <boost/corosio/native/detail/posix/posix_signal_service.hpp>
22 #endif
23
24 #if BOOST_COROSIO_HAS_IOCP
25 #include <boost/corosio/native/detail/iocp/win_signals.hpp>
26 #endif
27 #endif // !BOOST_COROSIO_MRDOCS
28
29 namespace boost::corosio {
30
31 /** Waits for a registered signal, calling the backend directly.
32
33 This class template inherits from @ref signal_set. It shadows the
34 `wait` operation with a version that calls the backend
35 implementation directly. The compiler can then inline through the
36 entire call chain.
37
38 Non-async operations (`add`, `remove`, `clear`, `cancel`)
39 remain unchanged and dispatch through the compiled library.
40
41 A `native_signal_set` IS-A `signal_set` and can be passed to
42 any function expecting `signal_set&`.
43
44 @tparam Backend A backend tag value (e.g., `epoll`).
45
46 @par Thread Safety
47 Same as @ref signal_set.
48
49 @see @ref signal_set, @ref epoll_t, @ref iocp_t
50 */
51 template<auto Backend>
52 class native_signal_set : public signal_set
53 {
54 using backend_type = decltype(Backend);
55 using impl_type = typename backend_type::signal_type;
56
57 impl_type& get_impl() noexcept
58 {
59 return *static_cast<impl_type*>(h_.get());
60 }
61
62 struct native_wait_awaitable
63 : detail::value_op_base<native_wait_awaitable, int>
64 {
65 native_signal_set& self_;
66
67 explicit native_wait_awaitable(native_signal_set& self) noexcept
68 : self_(self)
69 {
70 }
71
72 std::coroutine_handle<>
73 dispatch(capy::continuation& cont, capy::executor_ref ex) const
74 {
75 return self_.get_impl().wait(
76 cont, ex, this->token_, &this->ec_, &this->value_);
77 }
78 };
79
80 public:
81 /** Construct a native signal set from an execution context.
82
83 @param ctx The execution context that owns this signal set.
84 */
85 4x explicit native_signal_set(capy::execution_context& ctx) : signal_set(ctx)
86 {
87 4x }
88
89 /** Construct a native signal set with initial signals.
90
91 For the non-throwing form, construct with the context alone,
92 then call @ref signal_set::add for each signal.
93
94 @param ctx The execution context that owns this signal set.
95 @param signal First signal number to add.
96 @param signals Additional signal numbers to add.
97
98 @throws std::system_error on failure.
99
100 @see @ref signal_set::add
101 */
102 template<std::convertible_to<int>... Signals>
103 6x native_signal_set(
104 capy::execution_context& ctx, int signal, Signals... signals)
105 6x : signal_set(ctx, signal, signals...)
106 {
107 6x }
108
109 /** Construct a native signal set from an executor.
110
111 @param ex The executor whose context owns the signal set.
112
113 @tparam Ex A type satisfying @ref capy::Executor. Must not
114 be `native_signal_set` itself (disables implicit
115 conversion from move).
116 */
117 template<class Ex>
118 requires(!std::same_as<std::remove_cvref_t<Ex>, native_signal_set>) &&
119 capy::Executor<Ex>
120 2x explicit native_signal_set(Ex const& ex) : native_signal_set(ex.context())
121 {
122 2x }
123
124 /** Construct a native signal set from an executor with initial signals.
125
126 For the non-throwing form, construct with the executor alone,
127 then call @ref signal_set::add for each signal.
128
129 @param ex The executor whose context owns the signal set.
130 @param signal First signal number to add.
131 @param signals Additional signal numbers to add.
132
133 @tparam Ex A type satisfying @ref capy::Executor.
134
135 @throws std::system_error on failure.
136
137 @see @ref signal_set::add
138 */
139 template<class Ex, std::convertible_to<int>... Signals>
140 requires capy::Executor<Ex>
141 2x native_signal_set(Ex const& ex, int signal, Signals... signals)
142 2x : native_signal_set(ex.context(), signal, signals...)
143 {
144 2x }
145
146 /** Move construct.
147
148 @pre No awaitables returned by the source's methods exist.
149 @pre The execution context associated with the source must
150 outlive this signal set.
151 */
152 native_signal_set(native_signal_set&&) noexcept = default;
153
154 /** Move assign.
155
156 @pre No awaitables returned by either `*this` or the source's
157 methods exist.
158 @pre The execution context associated with the source must
159 outlive this signal set.
160 */
161 native_signal_set& operator=(native_signal_set&&) noexcept = default;
162
163 /// Copy construction is disabled; the handle is uniquely owned.
164 native_signal_set(native_signal_set const&) = delete;
165 /// Copy assignment is disabled; the handle is uniquely owned.
166 native_signal_set& operator=(native_signal_set const&) = delete;
167
168 /** Wait for a signal to be delivered.
169
170 Calls the backend implementation directly, bypassing virtual
171 dispatch. Otherwise identical to @ref signal_set::wait.
172
173 @return An awaitable yielding `results<int>`.
174
175 This signal set must outlive the returned awaitable.
176 */
177 [[nodiscard]] auto wait()
178 {
179 return native_wait_awaitable(*this);
180 }
181 };
182
183 } // namespace boost::corosio
184
185 #endif
186