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