4
4
//!
5
5
//! * [`Async`], an adapter for standard networking types (and [many other] types) to use in
6
6
//! async programs.
7
- //! * [`Timer`], a future that expires at a point in time .
7
+ //! * [`Timer`], a future or stream that emits timed events .
8
8
//!
9
9
//! For concrete async networking types built on top of this crate, see [`async-net`].
10
10
//!
@@ -85,14 +85,16 @@ mod reactor;
85
85
86
86
pub use driver:: block_on;
87
87
88
- /// Use Duration::MAX once duration_constants are stabilized.
88
+ /// Use ` Duration::MAX` once ` duration_constants` are stabilized.
89
89
fn duration_max ( ) -> Duration {
90
90
Duration :: new ( u64:: MAX , 1_000_000_000 - 1 )
91
91
}
92
92
93
- /// A future that expires at a point in time .
93
+ /// A future or stream that emits timed events .
94
94
///
95
- /// Timers are futures that output the [`Instant`] at which they fired.
95
+ /// Timers are futures that output a single [`Instant`] when they fire.
96
+ ///
97
+ /// Timers are also streams that can output [`Instant`]s periodically.
96
98
///
97
99
/// # Examples
98
100
///
@@ -130,15 +132,15 @@ pub struct Timer {
130
132
/// When this field is set to `None`, this timer is not registered in the reactor.
131
133
id_and_waker : Option < ( usize , Waker ) > ,
132
134
133
- /// When this timer fires.
135
+ /// The next instant at which this timer fires.
134
136
when : Instant ,
135
137
136
138
/// The period.
137
139
period : Duration ,
138
140
}
139
141
140
142
impl Timer {
141
- /// Creates a timer that expires after the given duration of time.
143
+ /// Creates a timer that emits an event once after the given duration of time.
142
144
///
143
145
/// # Examples
144
146
///
@@ -154,7 +156,7 @@ impl Timer {
154
156
Timer :: at ( Instant :: now ( ) + duration)
155
157
}
156
158
157
- /// Creates a timer that expires at the given time instant.
159
+ /// Creates a timer that emits an event once at the given time instant.
158
160
///
159
161
/// # Examples
160
162
///
@@ -173,7 +175,48 @@ impl Timer {
173
175
Timer :: interval_at ( instant, duration_max ( ) )
174
176
}
175
177
176
- /// Sets the timer to expire after the new duration of time.
178
+ /// Creates a timer that emits events periodically.
179
+ ///
180
+ /// # Examples
181
+ ///
182
+ /// ```
183
+ /// use async_io::Timer;
184
+ /// use futures_lite::StreamExt;
185
+ /// use std::time::{Duration, Instant};
186
+ ///
187
+ /// # futures_lite::future::block_on(async {
188
+ /// let period = Duration::from_secs(1);
189
+ /// Timer::interval(period).next().await;
190
+ /// # });
191
+ /// ```
192
+ pub fn interval ( period : Duration ) -> Timer {
193
+ Timer :: interval_at ( Instant :: now ( ) + period, period)
194
+ }
195
+
196
+ /// Creates a timer that emits events periodically, starting at `start`.
197
+ ///
198
+ /// # Examples
199
+ ///
200
+ /// ```
201
+ /// use async_io::Timer;
202
+ /// use futures_lite::StreamExt;
203
+ /// use std::time::{Duration, Instant};
204
+ ///
205
+ /// # futures_lite::future::block_on(async {
206
+ /// let start = Instant::now();
207
+ /// let period = Duration::from_secs(1);
208
+ /// Timer::interval_at(start, period).next().await;
209
+ /// # });
210
+ /// ```
211
+ pub fn interval_at ( start : Instant , period : Duration ) -> Timer {
212
+ Timer {
213
+ id_and_waker : None ,
214
+ when : start,
215
+ period,
216
+ }
217
+ }
218
+
219
+ /// Sets the timer to emit an en event once after the given duration of time.
177
220
///
178
221
/// Note that resetting a timer is different from creating a new timer because
179
222
/// [`set_after()`][`Timer::set_after()`] does not remove the waker associated with the task
@@ -194,10 +237,10 @@ impl Timer {
194
237
self . set_at ( Instant :: now ( ) + duration) ;
195
238
}
196
239
197
- /// Sets the timer to expire at the new time instant.
240
+ /// Sets the timer to emit an event once at the given time instant.
198
241
///
199
242
/// Note that resetting a timer is different from creating a new timer because
200
- /// [`set_after ()`][`Timer::set_after ()`] does not remove the waker associated with the task
243
+ /// [`set_at ()`][`Timer::set_at ()`] does not remove the waker associated with the task
201
244
/// that is polling the timer.
202
245
///
203
246
/// # Examples
@@ -229,7 +272,11 @@ impl Timer {
229
272
}
230
273
}
231
274
232
- /// Creates a timer that ticks every period.
275
+ /// Sets the timer to emit events periodically.
276
+ ///
277
+ /// Note that resetting a timer is different from creating a new timer because
278
+ /// [`set_interval()`][`Timer::set_interval()`] does not remove the waker associated with the
279
+ /// task that is polling the timer.
233
280
///
234
281
/// # Examples
235
282
///
@@ -239,15 +286,21 @@ impl Timer {
239
286
/// use std::time::{Duration, Instant};
240
287
///
241
288
/// # futures_lite::future::block_on(async {
242
- /// let period = Duration::from_secs(1);
243
- /// Timer::interval(period).next().await;
289
+ /// let mut t = Timer::after(Duration::from_secs(1));
290
+ ///
291
+ /// let period = Duration::from_secs(2);
292
+ /// t.set_interval(period);
244
293
/// # });
245
294
/// ```
246
- pub fn interval ( period : Duration ) -> Timer {
247
- Timer :: interval_at ( Instant :: now ( ) + period, period)
295
+ pub fn set_interval ( & mut self , period : Duration ) {
296
+ self . set_interval_at ( Instant :: now ( ) + period, period) ;
248
297
}
249
298
250
- /// Creates a timer that ticks every period, starting at `start`.
299
+ /// Sets the timer to emit events periodically, starting at `start`.
300
+ ///
301
+ /// Note that resetting a timer is different from creating a new timer because
302
+ /// [`set_interval_at()`][`Timer::set_interval_at()`] does not remove the waker associated with
303
+ /// the task that is polling the timer.
251
304
///
252
305
/// # Examples
253
306
///
@@ -257,16 +310,25 @@ impl Timer {
257
310
/// use std::time::{Duration, Instant};
258
311
///
259
312
/// # futures_lite::future::block_on(async {
260
- /// let now = Instant::now();
261
- /// let period = Duration::from_secs(1);
262
- /// Timer::interval_at(now, period).next().await;
313
+ /// let mut t = Timer::after(Duration::from_secs(1));
314
+ ///
315
+ /// let start = Instant::now();
316
+ /// let period = Duration::from_secs(2);
317
+ /// t.set_interval_at(start, period);
263
318
/// # });
264
319
/// ```
265
- pub fn interval_at ( start : Instant , period : Duration ) -> Timer {
266
- Timer {
267
- id_and_waker : None ,
268
- when : start,
269
- period : period,
320
+ pub fn set_interval_at ( & mut self , start : Instant , period : Duration ) {
321
+ if let Some ( ( id, _) ) = self . id_and_waker . as_ref ( ) {
322
+ // Deregister the timer from the reactor.
323
+ Reactor :: get ( ) . remove_timer ( self . when , * id) ;
324
+ }
325
+
326
+ self . when = start;
327
+ self . period = period;
328
+
329
+ if let Some ( ( id, waker) ) = self . id_and_waker . as_mut ( ) {
330
+ // Re-register the timer with the new timeout.
331
+ * id = Reactor :: get ( ) . insert_timer ( self . when , waker) ;
270
332
}
271
333
}
272
334
}
0 commit comments