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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>) :67 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>>>) :100 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; they are
34 never swallowed by the timer.
35
36 @par Preconditions
37 The awaiting coroutine's executor must belong to an
38 `io_context`; any other execution context terminates with a
39 diagnostic.
40
41 @par Cancellation
42 If the parent's stop token is activated, the inner awaitable
43 is cancelled and its cancellation result is returned. Requesting
44 stop from another thread requires a multi-threaded-capable
45 io_context; a context running in single_threaded mode
46 (auto-enabled at concurrency_hint == 1) does not permit
47 cross-thread cancellation.
48
49 @par Example
50 @par !example timeout
51
52 @param a The awaitable to race against the deadline.
53 @param dur The maximum duration to wait, measured from
54 suspension.
55
56 @return An awaitable yielding `io_result` matching the inner
57 awaitable's result type.
58
59 @see delay
60 */
61 template<capy::IoAwaitable A, typename Rep, typename Period>
62 requires detail::is_io_result_v<
63 std::remove_cvref_t<capy::awaitable_result_t<A>>> &&
64 std::is_default_constructible_v<
65 std::remove_cvref_t<capy::awaitable_result_t<A>>>
66 [[nodiscard]] auto
67 2055x timeout(A a, std::chrono::duration<Rep, Period> dur)
68 {
69 using namespace std::chrono;
70 // Narrow reps wrap if nanoseconds::max() is converted into them;
71 // a double comparison clamps safely in both directions.
72 using dsec = duration<double>;
73
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)()
74
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)())
75 2x ? (nanoseconds::min)()
76 2051x : duration_cast<nanoseconds>(dur);
77 2055x return detail::timeout_awaitable<A>(std::move(a), ns);
78 }
79
80 /** Race an io_result-returning awaitable against an absolute deadline.
81
82 Behaves as the duration overload with the deadline fixed at
83 `tp` instead of measured from suspension.
84
85 @param a The awaitable to race against the deadline.
86 @param tp The steady-clock time point at which the awaitable
87 is cancelled.
88
89 @return An awaitable yielding `io_result` matching the inner
90 awaitable's result type.
91
92 @see delay
93 */
94 template<capy::IoAwaitable A>
95 requires detail::is_io_result_v<
96 std::remove_cvref_t<capy::awaitable_result_t<A>>> &&
97 std::is_default_constructible_v<
98 std::remove_cvref_t<capy::awaitable_result_t<A>>>
99 [[nodiscard]] auto
100 4x timeout(A a, std::chrono::steady_clock::time_point tp)
101 {
102 4x return detail::timeout_awaitable<A>(std::move(a), tp);
103 }
104
105 } // namespace boost::corosio
106
107 #endif
108