include/boost/corosio/cancel.hpp

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