include/boost/corosio/timeout.hpp

100.0% Lines (8/8) 100.0% List of functions (25/25) 48.9% Branches (43/88)
timeout.hpp
f(x) Functions (25)
Function Calls Lines Branches Blocks
auto boost::corosio::timeout<boost::capy::task<std::__1::tuple<std::__1::error_code, int>>, long long, std::__1::ratio<1l, 1000l>>(boost::capy::task<std::__1::tuple<std::__1::error_code, int>>, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 2x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, int, std::__1::ratio<1l, 1000l>>(boost::corosio::delay_awaitable, std::__1::chrono::duration<int, std::__1::ratio<1l, 1000l>>) :66 2x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long long, std::__1::ratio<1l, 1000l>>(boost::corosio::delay_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 2008x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::delay_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 6x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long long, std::__1::ratio<3600l, 1l>>(boost::corosio::delay_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<3600l, 1l>>) :66 2x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long, std::__1::ratio<3600l, 1l>>(boost::corosio::delay_awaitable, std::__1::chrono::duration<long, std::__1::ratio<3600l, 1l>>) :66 6x 83.3% 75.0% 85.0% auto boost::corosio::timeout<boost::corosio::detail::timeout_awaitable<boost::corosio::delay_awaitable>, long long, std::__1::ratio<1l, 1l>>(boost::corosio::detail::timeout_awaitable<boost::corosio::delay_awaitable>, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 2x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::io_read_stream::read_some_awaitable<boost::capy::mutable_buffer>, long long, std::__1::ratio<1l, 1000l>>(boost::corosio::io_read_stream::read_some_awaitable<boost::capy::mutable_buffer>, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 3x 83.3% 50.0% 71.0% auto boost::corosio::timeout<boost::corosio::payload_awaitable, long long, std::__1::ratio<1l, 1000l>>(boost::corosio::payload_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 2x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::payload_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::payload_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 2x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::tcp_socket::connect_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::tcp_socket::connect_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 1x 83.3% 50.0% 71.0% auto boost::corosio::timeout<boost::corosio::tcp_socket::wait_awaitable, long long, std::__1::ratio<1l, 1000l>>(boost::corosio::tcp_socket::wait_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 1x 83.3% 50.0% 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 1x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testInnerExceptionPropagates()::throwing_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testInnerExceptionPropagates()::throwing_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 1x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testReadyInnerCanceledNotRemapped()::ready_canceled_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testReadyInnerCanceledNotRemapped()::ready_canceled_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 1x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testReadyInnerCompletesWithoutSuspend()::ready_awaitable, long long, std::__1::ratio<1l, 1000l>>(boost::corosio::timeout_test<boost::corosio::kqueue_t{}>::testReadyInnerCompletesWithoutSuspend()::ready_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 1x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 1x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerExceptionPropagates()::throwing_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerExceptionPropagates()::throwing_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 1x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::select_t{}>::testReadyInnerCanceledNotRemapped()::ready_canceled_awaitable, long long, std::__1::ratio<1l, 1l>>(boost::corosio::timeout_test<boost::corosio::select_t{}>::testReadyInnerCanceledNotRemapped()::ready_canceled_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 1x 100.0% 47.7% 71.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::select_t{}>::testReadyInnerCompletesWithoutSuspend()::ready_awaitable, long long, std::__1::ratio<1l, 1000l>>(boost::corosio::timeout_test<boost::corosio::select_t{}>::testReadyInnerCompletesWithoutSuspend()::ready_awaitable, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 1x 100.0% – 71.0% boost::capy::const_buffer boost::corosio::timeout<auto boost::capy::any_write_stream::write_some<boost::capy::const_buffer>(boost::capy::const_buffer)::awaitable, long long, std::__1::ratio<1l, 1l>>(auto boost::capy::any_write_stream::write_some<boost::capy::const_buffer>(boost::capy::const_buffer)::awaitable, std::__1::ratio::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 2x 100.0% – 71.0% boost::capy::mutable_buffer boost::corosio::timeout<auto boost::capy::any_read_stream::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer)::awaitable, long long, std::__1::ratio<1l, 1000l>>(auto boost::capy::any_read_stream::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer)::awaitable, std::__1::ratio::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :66 2x 100.0% – 71.0% boost::capy::mutable_buffer boost::corosio::timeout<auto boost::capy::any_read_stream::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer)::awaitable, long long, std::__1::ratio<1l, 1l>>(auto boost::capy::any_read_stream::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer)::awaitable, std::__1::ratio::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 4x 100.0% – 71.0% boost::capy::mutable_buffer boost::corosio::timeout<boost::corosio::detail::timeout_awaitable<auto boost::capy::any_read_stream::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer)::awaitable>, long long, std::__1::ratio<1l, 1l>>(auto boost::capy::any_read_stream::read_some<boost::capy::mutable_buffer>(boost::capy::mutable_buffer)::awaitable, std::__1::ratio::chrono::duration<long long, std::__1::ratio<1l, 1l>>) :66 2x 100.0% – 71.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable>(boost::corosio::delay_awaitable, std::__1::chrono::time_point<std::__1::chrono::time_point::steady_clock, std::__1::chrono::time_point::duration<long long, std::__1::chrono::ratio<1l, 1000000000l>>>) :99 4x 100.0% – 100.0%
Line Branch TLA Hits 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_TIMEOUT_HPP
12 #define BOOST_COROSIO_TIMEOUT_HPP
13
14 #include <boost/corosio/detail/config.hpp>
15 #include <boost/corosio/detail/timeout_awaitable.hpp>
16 #include <boost/capy/concept/io_awaitable.hpp>
17
18 #include <chrono>
19 #include <type_traits>
20 #include <utility>
21
22 namespace boost::corosio {
23
24 /** Race an io_result-returning awaitable against a deadline.
25
26 Starts the awaitable with an interposed stop token and arms a
27 timer. If the awaitable finishes first, its result is returned
28 as-is (success, error, or exception). If the deadline passes
29 first, the awaitable is cancelled and an `io_result` whose
30 `ec` compares equal to `capy::cond::timeout` (with a
31 default-initialized payload) is produced.
32
33 Exceptions from the inner awaitable always propagate to the caller.
34
35 @pre The awaiting coroutine's executor must belong to an
36 `io_context`. Any other execution context terminates with a
37 diagnostic, because silently running without a timer would
38 drop the requested timeout.
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 @par !example timeout
50
51 @param a The awaitable to race against the deadline.
52 @param dur The maximum duration to wait, measured from
53 suspension.
54
55 @return An awaitable yielding `io_result` matching the inner
56 awaitable's result type.
57
58 @see delay
59 */
60 template<capy::IoAwaitable A, typename Rep, typename Period>
61 requires detail::is_io_result_v<
62 std::remove_cvref_t<capy::awaitable_result_t<A>>> &&
63 std::is_default_constructible_v<
64 std::remove_cvref_t<capy::awaitable_result_t<A>>>
65 [[nodiscard]] auto
66 2055x timeout(A a, std::chrono::duration<Rep, Period> dur)
67 {
68 using namespace std::chrono;
69 // Narrow reps wrap if nanoseconds::max() is converted into them;
70 // a double comparison clamps safely in both directions.
71 using dsec = duration<double>;
72
22/44
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2008 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 2 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 4 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 2 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 2 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 2 times.
✗ Branch 34 not taken.
✓ Branch 35 taken 2 times.
✗ Branch 36 not taken.
✓ Branch 37 taken 1 time.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 time.
✗ Branch 40 not taken.
✓ Branch 41 taken 1 time.
✗ Branch 42 not taken.
✓ Branch 43 taken 1 time.
4108x auto ns = dsec(dur) >= dsec((nanoseconds::max)()) ? (nanoseconds::max)()
73
21/44
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2008 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 time.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 time.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 time.
✗ Branch 12 not taken.
✓ Branch 13 taken 1 time.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 2 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 4 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✓ Branch 27 taken 2 times.
✗ Branch 28 not taken.
✓ Branch 29 taken 2 times.
✗ Branch 30 not taken.
✓ Branch 31 taken 2 times.
✗ Branch 32 not taken.
✓ Branch 33 taken 2 times.
✓ Branch 34 taken 2 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✓ Branch 37 taken 1 time.
✗ Branch 38 not taken.
✓ Branch 39 taken 1 time.
✗ Branch 40 not taken.
✓ Branch 41 taken 1 time.
✗ Branch 42 not taken.
✓ Branch 43 taken 1 time.
2053x : dsec(dur) <= dsec((nanoseconds::min)())
74 2x ? (nanoseconds::min)()
75 2051x : duration_cast<nanoseconds>(dur);
76 2055x return detail::timeout_awaitable<A>(std::move(a), ns);
77 }
78
79 /** Race an io_result-returning awaitable against an absolute deadline.
80
81 Behaves as the duration overload with the deadline fixed at
82 `tp` instead of measured from suspension.
83
84 @param a The awaitable to race against the deadline.
85 @param tp The steady-clock time point at which the awaitable
86 is cancelled.
87
88 @return An awaitable yielding `io_result` matching the inner
89 awaitable's result type.
90
91 @see delay
92 */
93 template<capy::IoAwaitable A>
94 requires detail::is_io_result_v<
95 std::remove_cvref_t<capy::awaitable_result_t<A>>> &&
96 std::is_default_constructible_v<
97 std::remove_cvref_t<capy::awaitable_result_t<A>>>
98 [[nodiscard]] auto
99 4x timeout(A a, std::chrono::steady_clock::time_point tp)
100 {
101 4x return detail::timeout_awaitable<A>(std::move(a), tp);
102 }
103
104 } // namespace boost::corosio
105
106 #endif
107