TLA Line data 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 HIT 2 : explicit native_signal_set(capy::execution_context& ctx) : signal_set(ctx)
86 : {
87 2 : }
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 4 : native_signal_set(
104 : capy::execution_context& ctx, int signal, Signals... signals)
105 4 : : signal_set(ctx, signal, signals...)
106 : {
107 4 : }
108 :
109 : /** Move construct.
110 :
111 : @pre No awaitables returned by the source's methods exist.
112 : @pre The execution context associated with the source must
113 : outlive this signal set.
114 : */
115 : native_signal_set(native_signal_set&&) noexcept = default;
116 :
117 : /** Move assign.
118 :
119 : @pre No awaitables returned by either `*this` or the source's
120 : methods exist.
121 : @pre The execution context associated with the source must
122 : outlive this signal set.
123 : */
124 : native_signal_set& operator=(native_signal_set&&) noexcept = default;
125 :
126 : /// Copy construction is disabled; the handle is uniquely owned.
127 : native_signal_set(native_signal_set const&) = delete;
128 : /// Copy assignment is disabled; the handle is uniquely owned.
129 : native_signal_set& operator=(native_signal_set const&) = delete;
130 :
131 : /** Wait for a signal to be delivered.
132 :
133 : Calls the backend implementation directly, bypassing virtual
134 : dispatch. Otherwise identical to @ref signal_set::wait.
135 :
136 : @return An awaitable yielding `results<int>`.
137 :
138 : This signal set must outlive the returned awaitable.
139 : */
140 : [[nodiscard]] auto wait()
141 : {
142 : return native_wait_awaitable(*this);
143 : }
144 : };
145 :
146 : } // namespace boost::corosio
147 :
148 : #endif
|