include/boost/corosio/timeout.hpp

100.0% Lines (9/9) 100.0% List of functions (16/16)
timeout.hpp
f(x) Functions (16)
Function Calls Lines Blocks
auto boost::corosio::timeout<boost::capy::task<boost::capy::io_result<int> >, long, std::ratio<1l, 1000l> >(boost::capy::task<boost::capy::io_result<int> >, std::chrono::duration<long, std::ratio<1l, 1000l> >) :70 3x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, int, std::ratio<1l, 1000l> >(boost::corosio::delay_awaitable, std::chrono::duration<int, std::ratio<1l, 1000l> >) :70 3x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long, std::ratio<1l, 1000l> >(boost::corosio::delay_awaitable, std::chrono::duration<long, std::ratio<1l, 1000l> >) :70 3012x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::delay_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 9x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::delay_awaitable, long, std::ratio<3600l, 1l> >(boost::corosio::delay_awaitable, std::chrono::duration<long, std::ratio<3600l, 1l> >) :70 12x 100.0% 78.0% auto boost::corosio::timeout<boost::corosio::detail::timeout_awaitable<boost::corosio::delay_awaitable>, long, std::ratio<1l, 1l> >(boost::corosio::detail::timeout_awaitable<boost::corosio::delay_awaitable>, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 3x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::io_read_stream::read_some_awaitable<boost::capy::mutable_buffer>, long, std::ratio<1l, 1000l> >(boost::corosio::io_read_stream::read_some_awaitable<boost::capy::mutable_buffer>, std::chrono::duration<long, std::ratio<1l, 1000l> >) :70 3x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::payload_awaitable, long, std::ratio<1l, 1000l> >(boost::corosio::payload_awaitable, std::chrono::duration<long, std::ratio<1l, 1000l> >) :70 3x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::payload_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::payload_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 3x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::epoll_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::timeout_test<boost::corosio::epoll_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 1x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::epoll_t{}>::testInnerExceptionPropagates()::throwing_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::timeout_test<boost::corosio::epoll_t{}>::testInnerExceptionPropagates()::throwing_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 1x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::io_uring_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::timeout_test<boost::corosio::io_uring_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 1x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::io_uring_t{}>::testInnerExceptionPropagates()::throwing_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::timeout_test<boost::corosio::io_uring_t{}>::testInnerExceptionPropagates()::throwing_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 1x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerErrorPassesThrough()::erroring_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 1x 100.0% 70.0% auto boost::corosio::timeout<boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerExceptionPropagates()::throwing_awaitable, long, std::ratio<1l, 1l> >(boost::corosio::timeout_test<boost::corosio::select_t{}>::testInnerExceptionPropagates()::throwing_awaitable, std::chrono::duration<long, std::ratio<1l, 1l> >) :70 1x 100.0% 70.0% 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, std::ratio<1l, 1000000000l> > >) :103 6x 100.0% 100.0%
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_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 3057x [[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 6093x auto ns = dsec(dur) >= dsec((nanoseconds::max)())
77 6093x ? (nanoseconds::max)()
78 3054x : dsec(dur) <= dsec((nanoseconds::min)())
79 3054x ? (nanoseconds::min)()
80 3051x : duration_cast<nanoseconds>(dur);
81 6114x 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 6x [[nodiscard]] auto timeout(A a, std::chrono::steady_clock::time_point tp)
104 {
105 6x return detail::timeout_awaitable<A>(std::move(a), tp);
106 }
107
108 } // namespace boost::corosio
109
110 #endif
111