-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathtimer.hpp
More file actions
201 lines (153 loc) · 5.87 KB
/
timer.hpp
File metadata and controls
201 lines (153 loc) · 5.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
//
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
// Copyright (c) 2026 Steve Gerbino
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/cppalliance/corosio
//
#ifndef BOOST_COROSIO_TIMER_HPP
#define BOOST_COROSIO_TIMER_HPP
#include <boost/corosio/detail/config.hpp>
#include <boost/corosio/io/io_timer.hpp>
#include <boost/capy/ex/execution_context.hpp>
#include <boost/capy/concept/executor.hpp>
#include <chrono>
#include <cstddef>
namespace boost::corosio {
/** An asynchronous timer for coroutine I/O.
This class provides asynchronous timer operations that return
awaitable types. The timer can be used to schedule operations
to occur after a specified duration or at a specific time point.
Multiple coroutines may wait concurrently on the same timer.
When the timer expires, all waiters complete with success. When
the timer is cancelled, all waiters complete with an error that
compares equal to `capy::cond::canceled`.
Each timer operation participates in the affine awaitable protocol,
ensuring coroutines resume on the correct executor.
@par Thread Safety
Distinct objects: Safe.@n
Shared objects: Unsafe.
@par Semantics
Wraps platform timer facilities via the io_context reactor.
Operations dispatch to OS timer APIs (timerfd, IOCP timers,
kqueue EVFILT_TIMER).
*/
class BOOST_COROSIO_DECL timer : public io_timer
{
public:
/// Alias for backward compatibility.
using implementation = io_timer::implementation;
/** Destructor.
Cancels any pending operations and releases timer resources.
*/
~timer() override;
/** Construct a timer from an execution context.
@param ctx The execution context that will own this timer.
*/
explicit timer(capy::execution_context& ctx);
/** Construct a timer with an initial absolute expiry time.
@param ctx The execution context that will own this timer.
@param t The initial expiry time point.
*/
timer(capy::execution_context& ctx, time_point t);
/** Construct a timer with an initial relative expiry time.
@param ctx The execution context that will own this timer.
@param d The initial expiry duration relative to now.
*/
template<class Rep, class Period>
timer(capy::execution_context& ctx, std::chrono::duration<Rep, Period> d)
: timer(ctx)
{
expires_after(d);
}
/** Move constructor.
Transfers ownership of the timer resources.
@param other The timer to move from.
@pre No awaitables returned by @p other's methods exist.
@pre The execution context associated with @p other must
outlive this timer.
*/
timer(timer&& other) noexcept;
/** Move assignment operator.
Closes any existing timer and transfers ownership.
@param other The timer to move from.
@pre No awaitables returned by either `*this` or @p other's
methods exist.
@pre The execution context associated with @p other must
outlive this timer.
@return Reference to this timer.
*/
timer& operator=(timer&& other) noexcept;
timer(timer const&) = delete;
timer& operator=(timer const&) = delete;
/** Cancel one pending asynchronous wait operation.
The oldest pending wait is cancelled (FIFO order). It
completes with an error code that compares equal to
`capy::cond::canceled`.
@return The number of operations that were cancelled (0 or 1).
*/
std::size_t cancel_one()
{
if (!get().might_have_pending_waits_)
return 0;
return do_cancel_one();
}
/** Set the timer's expiry time as an absolute time.
Any pending asynchronous wait operations will be cancelled.
@param t The expiry time to be used for the timer.
@return The number of pending operations that were cancelled.
*/
std::size_t expires_at(time_point t)
{
auto& impl = get();
impl.expiry_ = t;
if (impl.heap_index_ == implementation::npos &&
!impl.might_have_pending_waits_)
return 0;
return do_update_expiry();
}
/** Set the timer's expiry time relative to now.
Any pending asynchronous wait operations will be cancelled.
@param d The expiry time relative to now.
@return The number of pending operations that were cancelled.
*/
std::size_t expires_after(duration d)
{
auto& impl = get();
if (d <= duration::zero())
impl.expiry_ = (time_point::min)();
else
impl.expiry_ = clock_type::now() + d;
if (impl.heap_index_ == implementation::npos &&
!impl.might_have_pending_waits_)
return 0;
return do_update_expiry();
}
/** Set the timer's expiry time relative to now.
This is a convenience overload that accepts any duration type
and converts it to the timer's native duration type. Any
pending asynchronous wait operations will be cancelled.
@param d The expiry time relative to now.
@return The number of pending operations that were cancelled.
*/
template<class Rep, class Period>
std::size_t expires_after(std::chrono::duration<Rep, Period> d)
{
return expires_after(std::chrono::duration_cast<duration>(d));
}
protected:
explicit timer(handle h) noexcept : io_timer(std::move(h)) {}
private:
std::size_t do_cancel() override;
std::size_t do_cancel_one();
std::size_t do_update_expiry();
/// Return the underlying implementation.
implementation& get() const noexcept
{
return *static_cast<implementation*>(h_.get());
}
};
} // namespace boost::corosio
#endif