include/boost/corosio/timeout.hpp
100.0% Lines (9/9)
100.0% List of functions (15/15)
48.2% Branches (27/56)
Functions (15)
Function
Calls
Lines
Branches
Blocks
auto boost::corosio::timeout<boost::capy::task<boost::capy::io_result<int>>, long long, std::__1::ratio<1l, 1000l>>(boost::capy::task<boost::capy::io_result<int>>, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>)
:70
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>>)
:70
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>>)
:70
2007x
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>>)
:70
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>>)
:70
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>>)
:70
6x
85.7%
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>>)
:70
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>>)
:70
2x
100.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>>)
:70
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>>)
:70
2x
100.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>>)
:70
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>>)
:70
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>>)
:70
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>>)
:70
1x
85.7%
46.4%
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>>>)
:103
4x
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 | 2037x | [[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 |
14/28✓ Branch 0 taken 2 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2007 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 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 2 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✗ Branch 22 not taken.
✓ Branch 23 taken 2 times.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 time.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 time.
|
4072x | auto ns = dsec(dur) >= dsec((nanoseconds::max)()) | |
| 77 | 2x | ? (nanoseconds::max)() | ||
| 78 |
13/28✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2007 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 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 2 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2 times.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 1 time.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 time.
|
2035x | : dsec(dur) <= dsec((nanoseconds::min)()) | |
| 79 | 2x | ? (nanoseconds::min)() | ||
| 80 | 2033x | : duration_cast<nanoseconds>(dur); | ||
| 81 | 2037x | 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 | 4x | [[nodiscard]] auto timeout(A a, std::chrono::steady_clock::time_point tp) | ||
| 104 | { | |||
| 105 | 4x | return detail::timeout_awaitable<A>(std::move(a), tp); | ||
| 106 | } | |||
| 107 | ||||
| 108 | } // namespace boost::corosio | |||
| 109 | ||||
| 110 | #endif | |||
| 111 |