include/boost/corosio/native/native_timer.hpp

93.9% Lines (31/33) 91.7% List of functions (22/24) 60.0% Branches (12/20)
f(x) Functions (24)
Function Calls Lines Branches Blocks
boost::corosio::native_timer<boost::corosio::kqueue_t{}>::~native_timer() :42 16x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::~native_timer() :42 16x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::get_impl() :46 5x 0.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::get_impl() :46 5x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_wait_awaitable&&) :51 10x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_wait_awaitable::~native_wait_awaitable() :51 20x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_timer<boost::corosio::select_t{}>::native_wait_awaitable&&) :51 10x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_wait_awaitable::~native_wait_awaitable() :51 20x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_timer<boost::corosio::kqueue_t{}>&) :57 10x 0.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_wait_awaitable::native_wait_awaitable(boost::corosio::native_timer<boost::corosio::select_t{}>&) :57 10x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_wait_awaitable::await_ready() const :62 5x 0.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_wait_awaitable::await_ready() const :62 5x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_wait_awaitable::await_resume() const :67 5x 0.0% 0.0% 75.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_wait_awaitable::await_resume() const :67 5x 80.0% 50.0% 75.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_wait_awaitable::await_suspend(std::__1::coroutine_handle<void>, boost::capy::io_env const*) :74 5x 0.0% 0.0% 81.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_wait_awaitable::await_suspend(std::__1::coroutine_handle<void>, boost::capy::io_env const*) :74 5x 100.0% 62.5% 81.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_timer(boost::capy::execution_context&) :98 14x 0.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_timer(boost::capy::execution_context&) :98 14x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_timer<long long, std::__1::ratio<1l, 1000l>>(boost::capy::execution_context&, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :113 2x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_timer<long long, std::__1::ratio<1l, 1000l>>(boost::capy::execution_context&, std::__1::chrono::duration<long long, std::__1::ratio<1l, 1000l>>) :113 2x 100.0% 100.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::native_timer(boost::corosio::native_timer<boost::corosio::kqueue_t{}>&&) :127 0 100.0% 0.0% boost::corosio::native_timer<boost::corosio::select_t{}>::native_timer(boost::corosio::native_timer<boost::corosio::select_t{}>&&) :127 0 0.0% 0.0% boost::corosio::native_timer<boost::corosio::kqueue_t{}>::wait() :152 5x 0.0% 100.0% boost::corosio::native_timer<boost::corosio::select_t{}>::wait() :152 5x 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_NATIVE_NATIVE_TIMER_HPP
11 #define BOOST_COROSIO_NATIVE_NATIVE_TIMER_HPP
12
13 #include <boost/corosio/timer.hpp>
14 #include <boost/corosio/backend.hpp>
15 #include <boost/corosio/detail/timer_service.hpp>
16
17 namespace boost::corosio {
18
19 /** An asynchronous timer with devirtualized wait operations.
20
21 This class template inherits from @ref timer and shadows the
22 `wait` operation with a version that calls the backend
23 implementation directly, allowing the compiler to inline
24 through the entire call chain.
25
26 Non-async operations (`cancel`, `expires_at`, `expires_after`)
27 remain unchanged and dispatch through the compiled library.
28
29 A `native_timer` IS-A `timer` and can be passed to any function
30 expecting `timer&`.
31
32 @tparam Backend A backend tag value (e.g., `epoll`).
33 The timer implementation is backend-independent; the
34 tag selects the concrete impl type for devirtualization.
35
36 @par Thread Safety
37 Same as @ref timer.
38
39 @see timer, epoll_t, iocp_t
40 */
41 template<auto Backend>
42 class native_timer : public timer
43 {
44 using impl_type = detail::timer_service::implementation;
45
46 10x impl_type& get_impl() noexcept
47 {
48 10x return *static_cast<impl_type*>(h_.get());
49 }
50
51 struct native_wait_awaitable
52 {
53 native_timer& self_;
54 std::stop_token token_;
55 mutable std::error_code ec_;
56
57 30x explicit native_wait_awaitable(native_timer& self) noexcept
58 10x : self_(self)
59 10x {
60 20x }
61
62 10x bool await_ready() const noexcept
63 {
64 10x return token_.stop_requested();
65 }
66
67 10x capy::io_result<> await_resume() const noexcept
68 {
69
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
10x if (token_.stop_requested())
70 return {capy::error::canceled};
71 10x return {ec_};
72 10x }
73
74 10x auto await_suspend(std::coroutine_handle<> h, capy::io_env const* env)
75 -> std::coroutine_handle<>
76 {
77 10x token_ = env->stop_token;
78 10x auto& impl = self_.get_impl();
79 // Fast path: already expired and not in the heap
80
6/8
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1 time.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 time.
✓ Branch 7 taken 4 times.
20x if (impl.heap_index_ == timer::implementation::npos &&
81
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
10x (impl.expiry_ == (time_point::min)() ||
82 10x impl.expiry_ <= clock_type::now()))
83 {
84 2x ec_ = {};
85 2x auto d = env->executor;
86 2x d.post(h);
87 2x return std::noop_coroutine();
88 }
89
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
8x return impl.wait(h, env->executor, std::move(token_), &ec_);
90 10x }
91 };
92
93 public:
94 /** Construct a native timer from an execution context.
95
96 @param ctx The execution context that will own this timer.
97 */
98 28x explicit native_timer(capy::execution_context& ctx) : timer(ctx) {}
99
100 /** Construct a native timer with an initial absolute expiry.
101
102 @param ctx The execution context that will own this timer.
103 @param t The initial expiry time point.
104 */
105 native_timer(capy::execution_context& ctx, time_point t) : timer(ctx, t) {}
106
107 /** Construct a native timer with an initial relative expiry.
108
109 @param ctx The execution context that will own this timer.
110 @param d The initial expiry duration relative to now.
111 */
112 template<class Rep, class Period>
113 4x native_timer(
114 capy::execution_context& ctx, std::chrono::duration<Rep, Period> d)
115 2x : timer(ctx, d)
116 4x {
117 4x }
118
119 /** Move construct.
120
121 @param other The timer to move from.
122
123 @pre No awaitables returned by @p other's methods exist.
124 @pre The execution context associated with @p other must
125 outlive this timer.
126 */
127 native_timer(native_timer&&) noexcept = default;
128
129 /** Move assign.
130
131 @param other The timer to move from.
132
133 @pre No awaitables returned by either `*this` or @p other's
134 methods exist.
135 @pre The execution context associated with @p other must
136 outlive this timer.
137 */
138 native_timer& operator=(native_timer&&) noexcept = default;
139
140 native_timer(native_timer const&) = delete;
141 native_timer& operator=(native_timer const&) = delete;
142
143 /** Wait for the timer to expire.
144
145 Calls the backend implementation directly, bypassing virtual
146 dispatch. Otherwise identical to @ref timer::wait.
147
148 @return An awaitable yielding `io_result<>`.
149
150 This timer must outlive the returned awaitable.
151 */
152 10x auto wait()
153 {
154 10x return native_wait_awaitable(*this);
155 }
156 };
157
158 } // namespace boost::corosio
159
160 #endif
161