include/boost/corosio/timeout.hpp

100.0% Lines (9/9) 100.0% List of functions (12/12) 100.0% Branches (12/12)
timeout.hpp
f(x) Functions (12)
Function Calls Lines Branches Blocks
auto boost::corosio::timeout<boost::capy::task<boost::capy::io_result<int> >, long long, std::ratio<1ll, 1000ll> >(boost::capy::task<boost::capy::io_result<int> >, std::chrono::duration<long long, std::ratio<1ll, 1000ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::delay_awaitable, int, std::ratio<1ll, 1000ll> >(boost::corosio::delay_awaitable, std::chrono::duration<int, std::ratio<1ll, 1000ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long long, std::ratio<1ll, 1000ll> >(boost::corosio::delay_awaitable, std::chrono::duration<long long, std::ratio<1ll, 1000ll> >) :70 1004x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long long, std::ratio<1ll, 1ll> >(boost::corosio::delay_awaitable, std::chrono::duration<long long, std::ratio<1ll, 1ll> >) :70 3x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long long, std::ratio<3600ll, 1ll> >(boost::corosio::delay_awaitable, std::chrono::duration<long long, std::ratio<3600ll, 1ll> >) :70 4x 100.0% 100.0% 77.8% auto boost::corosio::timeout<boost::corosio::detail::timeout_awaitable<boost::corosio::delay_awaitable>, long long, std::ratio<1ll, 1ll> >(boost::corosio::detail::timeout_awaitable<boost::corosio::delay_awaitable>, std::chrono::duration<long long, std::ratio<1ll, 1ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::io_read_stream::read_some_awaitable<boost::capy::mutable_buffer>, long long, std::ratio<1ll, 1000ll> >(boost::corosio::io_read_stream::read_some_awaitable<boost::capy::mutable_buffer>, std::chrono::duration<long long, std::ratio<1ll, 1000ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::payload_awaitable, long long, std::ratio<1ll, 1000ll> >(boost::corosio::payload_awaitable, std::chrono::duration<long long, std::ratio<1ll, 1000ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::payload_awaitable, long long, std::ratio<1ll, 1ll> >(boost::corosio::payload_awaitable, std::chrono::duration<long long, std::ratio<1ll, 1ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::iocp_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, long long, std::ratio<1ll, 1ll> >(boost::corosio::timeout_test<boost::corosio::iocp_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, std::chrono::duration<long long, std::ratio<1ll, 1ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::iocp_t{}>::testInnerExceptionPropagates()::throwing_awaitable, long long, std::ratio<1ll, 1ll> >(boost::corosio::timeout_test<boost::corosio::iocp_t{}>::testInnerExceptionPropagates()::throwing_awaitable, std::chrono::duration<long long, std::ratio<1ll, 1ll> >) :70 1x 100.0% 83.3% 70.4% auto boost::corosio::timeout<boost::corosio::delay_awaitable>(boost::corosio::delay_awaitable, std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long long, std::ratio<1ll, 1000000000ll> > >) :103 2x 100.0% 100.0%
Line Branch 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_TIMEOUT_HPP
11 #define BOOST_COROSIO_TIMEOUT_HPP
12
13 #include <boost/corosio/detail/config.hpp>
14 #include <boost/corosio/detail/timeout_awaitable.hpp>
15 #include <boost/capy/concept/io_awaitable.hpp>
16
17 #include <chrono>
18 #include <type_traits>
19 #include <utility>
20
21 namespace boost::corosio {
22
23 /** Race an io_result-returning awaitable against a deadline.
24
25 Starts the awaitable with an interposed stop token and arms a
26 timer. If the awaitable finishes first, its result is returned
27 as-is (success, error, or exception). If the deadline passes
28 first, the awaitable is cancelled and an `io_result` whose
29 `ec` compares equal to `capy::cond::timeout` (with a
30 default-initialized payload) is produced.
31
32 Exceptions from the inner awaitable always propagate; they are
33 never swallowed by the timer.
34
35 @par Preconditions
36 The awaiting coroutine's executor must belong to an
37 `io_context`; any other execution context terminates with a
38 diagnostic.
39
40 @par Cancellation
41 If the parent's stop token is activated, the inner awaitable
42 is cancelled and its cancellation result is returned. Requesting
43 stop from another thread requires a multi-threaded-capable
44 io_context; a context running in single_threaded mode
45 (auto-enabled at concurrency_hint == 1) does not permit
46 cross-thread cancellation.
47
48 @par Example
49 @code
50 auto [ec, n] = co_await timeout(sock.read_some(buf), 50ms);
51 if (ec == capy::cond::timeout) {
52 // handle timeout
53 }
54 @endcode
55
56 @param a The awaitable to race against the deadline.
57 @param dur The maximum duration to wait, measured from
58 suspension.
59
60 @return An awaitable yielding `io_result` matching the inner
61 awaitable's result type.
62
63 @see delay
64 */
65 template<capy::IoAwaitable A, typename Rep, typename Period>
66 requires detail::is_io_result_v<
67 std::remove_cvref_t<capy::awaitable_result_t<A>>> &&
68 std::is_default_constructible_v<
69 std::remove_cvref_t<capy::awaitable_result_t<A>>>
70 1019x [[nodiscard]] auto timeout(A a, std::chrono::duration<Rep, Period> dur)
71 {
72 using namespace std::chrono;
73 // Narrow reps wrap if nanoseconds::max() is converted into them;
74 // a double comparison clamps safely in both directions.
75 using dsec = duration<double>;
76
3/3
✓ Branch 3 → 4 taken 1019 times.
✓ Branch 4 → 5 taken 1019 times.
✓ Branch 5 → 6 taken 1019 times.
1019x auto ns = dsec(dur) >= dsec((nanoseconds::max)())
77
2/2
✓ Branch 7 → 8 taken 1 time.
✓ Branch 7 → 9 taken 1018 times.
1019x ? (nanoseconds::max)()
78
3/3
✓ Branch 10 → 11 taken 1018 times.
✓ Branch 11 → 12 taken 1018 times.
✓ Branch 12 → 13 taken 1018 times.
1018x : dsec(dur) <= dsec((nanoseconds::min)())
79
2/2
✓ Branch 14 → 15 taken 1 time.
✓ Branch 14 → 16 taken 1017 times.
1018x ? (nanoseconds::min)()
80
1/1
✓ Branch 16 → 17 taken 1017 times.
1017x : duration_cast<nanoseconds>(dur);
81
1/1
✓ Branch 18 → 19 taken 1019 times.
2038x return detail::timeout_awaitable<A>(std::move(a), ns);
82 }
83
84 /** Race an io_result-returning awaitable against an absolute deadline.
85
86 Behaves as the duration overload with the deadline fixed at
87 `tp` instead of measured from suspension.
88
89 @param a The awaitable to race against the deadline.
90 @param tp The steady-clock time point at which the awaitable
91 is cancelled.
92
93 @return An awaitable yielding `io_result` matching the inner
94 awaitable's result type.
95
96 @see delay
97 */
98 template<capy::IoAwaitable A>
99 requires detail::is_io_result_v<
100 std::remove_cvref_t<capy::awaitable_result_t<A>>> &&
101 std::is_default_constructible_v<
102 std::remove_cvref_t<capy::awaitable_result_t<A>>>
103 2x [[nodiscard]] auto timeout(A a, std::chrono::steady_clock::time_point tp)
104 {
105 2x return detail::timeout_awaitable<A>(std::move(a), tp);
106 }
107
108 } // namespace boost::corosio
109
110 #endif
111