include/boost/corosio/native/native_cancel.hpp

100.0% Lines (6/6) 100.0% List of functions (4/4) -% Branches (0/0)
f(x) Functions (4)
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_NATIVE_NATIVE_CANCEL_HPP
11 #define BOOST_COROSIO_NATIVE_NATIVE_CANCEL_HPP
12
13 #include <boost/corosio/detail/cancel_at_awaitable.hpp>
14 #include <boost/corosio/native/native_timer.hpp>
15 #include <boost/capy/concept/io_awaitable.hpp>
16
17 #include <type_traits>
18 #include <utility>
19
20 namespace boost::corosio {
21
22 /** Cancel an operation if it does not complete by a deadline.
23
24 Overload for @ref native_timer that devirtualizes the internal
25 timer wait, allowing the compiler to inline the timer path.
26 Otherwise identical to the @ref timer overload.
27
28 If the deadline is reached first, the inner operation completes
29 with an error comparing equal to `capy::cond::canceled`. If the
30 inner operation completes first, the timer is cancelled. Parent
31 cancellation is forwarded to both.
32
33 The timer's expiry is overwritten by this call. The timer must
34 outlive the returned awaitable. Do not issue overlapping waits
35 on the same timer.
36
37 @par Completion Conditions
38 The returned awaitable resumes when either:
39 @li The inner operation completes (successfully or with error).
40 @li The deadline expires and the inner operation is cancelled.
41 @li The caller's stop token is triggered, cancelling both.
42
43 @par Error Conditions
44 @li On timeout or parent cancellation, the inner operation
45 completes with an error equal to `capy::cond::canceled`.
46 @li All other errors are propagated from the inner operation.
47
48 @par Example
49 @code
50 native_timer<epoll> t( ioc );
51 auto [ec, n] = co_await cancel_at(
52 sock.read_some( buf ), t,
53 clock::now() + 5s );
54 if (ec == capy::cond::canceled)
55 // timed out or parent cancelled
56 @endcode
57
58 @tparam Backend A backend tag value (e.g., `epoll`).
59
60 @param op The inner I/O awaitable to wrap.
61 @param t The native timer to use for the deadline. Must outlive
62 the returned awaitable.
63 @param deadline The absolute time point at which to cancel.
64
65 @return An awaitable whose result matches @p op's result type.
66
67 @see cancel_after, native_timer
68 */
69 template<auto Backend>
70 auto
71 cancel_at(
72 capy::IoAwaitable auto&& op,
73 native_timer<Backend>& t,
74 timer::time_point deadline)
75 {
76 return detail::cancel_at_awaitable<
77 std::decay_t<decltype(op)>, native_timer<Backend>>(
78 std::forward<decltype(op)>(op), t, deadline);
79 }
80
81 /** Cancel an operation if it does not complete within a duration.
82
83 Overload for @ref native_timer. Equivalent to
84 `cancel_at( op, t, clock::now() + timeout )`.
85
86 The timer's expiry is overwritten by this call. The timer must
87 outlive the returned awaitable. Do not issue overlapping waits
88 on the same timer.
89
90 @par Completion Conditions
91 The returned awaitable resumes when either:
92 @li The inner operation completes (successfully or with error).
93 @li The timeout elapses and the inner operation is cancelled.
94 @li The caller's stop token is triggered, cancelling both.
95
96 @par Error Conditions
97 @li On timeout or parent cancellation, the inner operation
98 completes with an error equal to `capy::cond::canceled`.
99 @li All other errors are propagated from the inner operation.
100
101 @par Example
102 @code
103 native_timer<epoll> t( ioc );
104 auto [ec, n] = co_await cancel_after(
105 sock.read_some( buf ), t, 5s );
106 if (ec == capy::cond::canceled)
107 // timed out
108 @endcode
109
110 @tparam Backend A backend tag value (e.g., `epoll`).
111
112 @param op The inner I/O awaitable to wrap.
113 @param t The native timer to use for the timeout. Must outlive
114 the returned awaitable.
115 @param timeout The relative duration after which to cancel.
116
117 @return An awaitable whose result matches @p op's result type.
118
119 @see cancel_at, native_timer
120 */
121 template<auto Backend>
122 auto
123 cancel_after(
124 capy::IoAwaitable auto&& op,
125 native_timer<Backend>& t,
126 timer::duration timeout)
127 {
128 return cancel_at(
129 std::forward<decltype(op)>(op), t, timer::clock_type::now() + timeout);
130 }
131
132 /** Cancel an operation if it does not complete by a deadline.
133
134 Convenience overload that creates a @ref native_timer internally,
135 devirtualizing the timer wait. Otherwise identical to the
136 explicit-timer overload.
137
138 @par Completion Conditions
139 The returned awaitable resumes when either:
140 @li The inner operation completes (successfully or with error).
141 @li The deadline expires and the inner operation is cancelled.
142 @li The caller's stop token is triggered, cancelling both.
143
144 @par Error Conditions
145 @li On timeout or parent cancellation, the inner operation
146 completes with an error equal to `capy::cond::canceled`.
147 @li All other errors are propagated from the inner operation.
148
149 @note Creates a timer per call. Use the explicit-timer overload
150 to amortize allocation across multiple timeouts.
151
152 @par Example
153 @code
154 auto [ec, n] = co_await cancel_at<epoll>(
155 sock.read_some( buf ),
156 clock::now() + 5s );
157 if (ec == capy::cond::canceled)
158 // timed out or parent cancelled
159 @endcode
160
161 @tparam Backend A backend tag value (e.g., `epoll`).
162
163 @param op The inner I/O awaitable to wrap.
164 @param deadline The absolute time point at which to cancel.
165
166 @return An awaitable whose result matches @p op's result type.
167
168 @see cancel_after, native_timer
169 */
170 template<auto Backend>
171 auto
172 6x cancel_at(capy::IoAwaitable auto&& op, timer::time_point deadline)
173 {
174 6x return detail::cancel_at_awaitable<
175 std::decay_t<decltype(op)>, native_timer<Backend>, true>(
176 6x std::forward<decltype(op)>(op), deadline);
177 }
178
179 /** Cancel an operation if it does not complete within a duration.
180
181 Convenience overload that creates a @ref native_timer internally.
182 Equivalent to `cancel_at<Backend>( op, clock::now() + timeout )`.
183
184 @par Completion Conditions
185 The returned awaitable resumes when either:
186 @li The inner operation completes (successfully or with error).
187 @li The timeout elapses and the inner operation is cancelled.
188 @li The caller's stop token is triggered, cancelling both.
189
190 @par Error Conditions
191 @li On timeout or parent cancellation, the inner operation
192 completes with an error equal to `capy::cond::canceled`.
193 @li All other errors are propagated from the inner operation.
194
195 @note Creates a timer per call. Use the explicit-timer overload
196 to amortize allocation across multiple timeouts.
197
198 @par Example
199 @code
200 auto [ec, n] = co_await cancel_after<epoll>(
201 sock.read_some( buf ), 5s );
202 if (ec == capy::cond::canceled)
203 // timed out
204 @endcode
205
206 @tparam Backend A backend tag value (e.g., `epoll`).
207
208 @param op The inner I/O awaitable to wrap.
209 @param timeout The relative duration after which to cancel.
210
211 @return An awaitable whose result matches @p op's result type.
212
213 @see cancel_at, native_timer
214 */
215 template<auto Backend>
216 auto
217 4x cancel_after(capy::IoAwaitable auto&& op, timer::duration timeout)
218 {
219 4x return cancel_at<Backend>(
220 4x std::forward<decltype(op)>(op), timer::clock_type::now() + timeout);
221 }
222
223 } // namespace boost::corosio
224
225 #endif
226