@@ -96,6 +96,12 @@ fn duration_max() -> Duration {
96
96
Duration :: new ( std:: u64:: MAX , 1_000_000_000 - 1 )
97
97
}
98
98
99
+ fn instant_max ( ) -> Instant {
100
+ // In order to ensure this point in time is never reached, it
101
+ // is put 30 years into the future.
102
+ Instant :: now ( ) + Duration :: from_secs ( 86400 * 365 * 30 )
103
+ }
104
+
99
105
/// A future or stream that emits timed events.
100
106
///
101
107
/// Timers are futures that output a single [`Instant`] when they fire.
@@ -139,13 +145,57 @@ pub struct Timer {
139
145
id_and_waker : Option < ( usize , Waker ) > ,
140
146
141
147
/// The next instant at which this timer fires.
142
- when : Instant ,
148
+ ///
149
+ /// If this timer is a blank timer, this value is None. If the timer
150
+ /// must be set, this value contains the next instant at which the
151
+ /// timer must fire.
152
+ when : Option < Instant > ,
143
153
144
154
/// The period.
145
155
period : Duration ,
146
156
}
147
157
148
158
impl Timer {
159
+ /// Creates a timer that will never fire.
160
+ ///
161
+ /// # Examples
162
+ ///
163
+ /// This function may also be useful for creating a function with an optional timeout.
164
+ ///
165
+ /// ```
166
+ /// # futures_lite::future::block_on(async {
167
+ /// use async_io::Timer;
168
+ /// use futures_lite::prelude::*;
169
+ /// use std::time::Duration;
170
+ ///
171
+ /// async fn run_with_timeout(timeout: Option<Duration>) {
172
+ /// let timer = timeout
173
+ /// .map(|timeout| Timer::after(timeout))
174
+ /// .unwrap_or_else(Timer::never);
175
+ ///
176
+ /// run_lengthy_operation().or(timer).await;
177
+ /// }
178
+ /// # // Note that since a Timer as a Future returns an Instant,
179
+ /// # // this function needs to return an Instant to be used
180
+ /// # // in "or".
181
+ /// # async fn run_lengthy_operation() -> std::time::Instant {
182
+ /// # std::time::Instant::now()
183
+ /// # }
184
+ ///
185
+ /// // Times out after 5 seconds.
186
+ /// run_with_timeout(Some(Duration::from_secs(5))).await;
187
+ /// // Does not time out.
188
+ /// run_with_timeout(None).await;
189
+ /// # });
190
+ /// ```
191
+ pub fn never ( ) -> Timer {
192
+ Timer {
193
+ id_and_waker : None ,
194
+ when : None ,
195
+ period : duration_max ( ) ,
196
+ }
197
+ }
198
+
149
199
/// Creates a timer that emits an event once after the given duration of time.
150
200
///
151
201
/// # Examples
@@ -159,7 +209,11 @@ impl Timer {
159
209
/// # });
160
210
/// ```
161
211
pub fn after ( duration : Duration ) -> Timer {
162
- Timer :: at ( Instant :: now ( ) + duration)
212
+ Timer :: at (
213
+ Instant :: now ( )
214
+ . checked_add ( duration)
215
+ . unwrap_or_else ( instant_max) ,
216
+ )
163
217
}
164
218
165
219
/// Creates a timer that emits an event once at the given time instant.
@@ -196,7 +250,12 @@ impl Timer {
196
250
/// # });
197
251
/// ```
198
252
pub fn interval ( period : Duration ) -> Timer {
199
- Timer :: interval_at ( Instant :: now ( ) + period, period)
253
+ Timer :: interval_at (
254
+ Instant :: now ( )
255
+ . checked_add ( period)
256
+ . unwrap_or_else ( instant_max) ,
257
+ period,
258
+ )
200
259
}
201
260
202
261
/// Creates a timer that emits events periodically, starting at `start`.
@@ -217,7 +276,7 @@ impl Timer {
217
276
pub fn interval_at ( start : Instant , period : Duration ) -> Timer {
218
277
Timer {
219
278
id_and_waker : None ,
220
- when : start,
279
+ when : Some ( start) ,
221
280
period,
222
281
}
223
282
}
@@ -240,7 +299,11 @@ impl Timer {
240
299
/// # });
241
300
/// ```
242
301
pub fn set_after ( & mut self , duration : Duration ) {
243
- self . set_at ( Instant :: now ( ) + duration) ;
302
+ self . set_at (
303
+ Instant :: now ( )
304
+ . checked_add ( duration)
305
+ . unwrap_or_else ( instant_max) ,
306
+ ) ;
244
307
}
245
308
246
309
/// Sets the timer to emit an event once at the given time instant.
@@ -264,17 +327,17 @@ impl Timer {
264
327
/// # });
265
328
/// ```
266
329
pub fn set_at ( & mut self , instant : Instant ) {
267
- if let Some ( ( id, _) ) = self . id_and_waker . as_ref ( ) {
330
+ if let ( Some ( when ) , Some ( ( id, _) ) ) = ( self . when , self . id_and_waker . as_ref ( ) ) {
268
331
// Deregister the timer from the reactor.
269
- Reactor :: get ( ) . remove_timer ( self . when , * id) ;
332
+ Reactor :: get ( ) . remove_timer ( when, * id) ;
270
333
}
271
334
272
335
// Update the timeout.
273
- self . when = instant;
336
+ self . when = Some ( instant) ;
274
337
275
338
if let Some ( ( id, waker) ) = self . id_and_waker . as_mut ( ) {
276
339
// Re-register the timer with the new timeout.
277
- * id = Reactor :: get ( ) . insert_timer ( self . when , waker) ;
340
+ * id = Reactor :: get ( ) . insert_timer ( instant , waker) ;
278
341
}
279
342
}
280
343
@@ -299,7 +362,12 @@ impl Timer {
299
362
/// # });
300
363
/// ```
301
364
pub fn set_interval ( & mut self , period : Duration ) {
302
- self . set_interval_at ( Instant :: now ( ) + period, period) ;
365
+ self . set_interval_at (
366
+ Instant :: now ( )
367
+ . checked_add ( period)
368
+ . unwrap_or_else ( instant_max) ,
369
+ period,
370
+ ) ;
303
371
}
304
372
305
373
/// Sets the timer to emit events periodically, starting at `start`.
@@ -324,26 +392,26 @@ impl Timer {
324
392
/// # });
325
393
/// ```
326
394
pub fn set_interval_at ( & mut self , start : Instant , period : Duration ) {
327
- if let Some ( ( id, _) ) = self . id_and_waker . as_ref ( ) {
395
+ if let ( Some ( when ) , Some ( ( id, _) ) ) = ( self . when , self . id_and_waker . as_ref ( ) ) {
328
396
// Deregister the timer from the reactor.
329
- Reactor :: get ( ) . remove_timer ( self . when , * id) ;
397
+ Reactor :: get ( ) . remove_timer ( when, * id) ;
330
398
}
331
399
332
- self . when = start;
400
+ self . when = Some ( start) ;
333
401
self . period = period;
334
402
335
403
if let Some ( ( id, waker) ) = self . id_and_waker . as_mut ( ) {
336
404
// Re-register the timer with the new timeout.
337
- * id = Reactor :: get ( ) . insert_timer ( self . when , waker) ;
405
+ * id = Reactor :: get ( ) . insert_timer ( start , waker) ;
338
406
}
339
407
}
340
408
}
341
409
342
410
impl Drop for Timer {
343
411
fn drop ( & mut self ) {
344
- if let Some ( ( id, _) ) = self . id_and_waker . take ( ) {
412
+ if let ( Some ( when ) , Some ( ( id, _) ) ) = ( self . when , self . id_and_waker . take ( ) ) {
345
413
// Deregister the timer from the reactor.
346
- Reactor :: get ( ) . remove_timer ( self . when , id) ;
414
+ Reactor :: get ( ) . remove_timer ( when, id) ;
347
415
}
348
416
}
349
417
}
@@ -363,39 +431,44 @@ impl Future for Timer {
363
431
impl Stream for Timer {
364
432
type Item = Instant ;
365
433
366
- fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
367
- // Check if the timer has already fired.
368
- if Instant :: now ( ) >= self . when {
369
- if let Some ( ( id, _) ) = self . id_and_waker . take ( ) {
370
- // Deregister the timer from the reactor.
371
- Reactor :: get ( ) . remove_timer ( self . when , id) ;
372
- }
373
- let when = self . when ;
374
- if let Some ( next) = when. checked_add ( self . period ) {
375
- self . when = next;
376
- // Register the timer in the reactor.
377
- let id = Reactor :: get ( ) . insert_timer ( self . when , cx. waker ( ) ) ;
378
- self . id_and_waker = Some ( ( id, cx. waker ( ) . clone ( ) ) ) ;
379
- }
380
- return Poll :: Ready ( Some ( when) ) ;
381
- } else {
382
- match & self . id_and_waker {
383
- None => {
434
+ fn poll_next ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
435
+ let this = self . get_mut ( ) ;
436
+
437
+ if let Some ( ref mut when) = this. when {
438
+ // Check if the timer has already fired.
439
+ if Instant :: now ( ) >= * when {
440
+ if let Some ( ( id, _) ) = this. id_and_waker . take ( ) {
441
+ // Deregister the timer from the reactor.
442
+ Reactor :: get ( ) . remove_timer ( * when, id) ;
443
+ }
444
+ let result_time = * when;
445
+ if let Some ( next) = ( * when) . checked_add ( this. period ) {
446
+ * when = next;
384
447
// Register the timer in the reactor.
385
- let id = Reactor :: get ( ) . insert_timer ( self . when , cx. waker ( ) ) ;
386
- self . id_and_waker = Some ( ( id, cx. waker ( ) . clone ( ) ) ) ;
448
+ let id = Reactor :: get ( ) . insert_timer ( next , cx. waker ( ) ) ;
449
+ this . id_and_waker = Some ( ( id, cx. waker ( ) . clone ( ) ) ) ;
387
450
}
388
- Some ( ( id, w) ) if !w. will_wake ( cx. waker ( ) ) => {
389
- // Deregister the timer from the reactor to remove the old waker.
390
- Reactor :: get ( ) . remove_timer ( self . when , * id) ;
391
-
392
- // Register the timer in the reactor with the new waker.
393
- let id = Reactor :: get ( ) . insert_timer ( self . when , cx. waker ( ) ) ;
394
- self . id_and_waker = Some ( ( id, cx. waker ( ) . clone ( ) ) ) ;
451
+ return Poll :: Ready ( Some ( result_time) ) ;
452
+ } else {
453
+ match & this. id_and_waker {
454
+ None => {
455
+ // Register the timer in the reactor.
456
+ let id = Reactor :: get ( ) . insert_timer ( * when, cx. waker ( ) ) ;
457
+ this. id_and_waker = Some ( ( id, cx. waker ( ) . clone ( ) ) ) ;
458
+ }
459
+ Some ( ( id, w) ) if !w. will_wake ( cx. waker ( ) ) => {
460
+ // Deregister the timer from the reactor to remove the old waker.
461
+ Reactor :: get ( ) . remove_timer ( * when, * id) ;
462
+
463
+ // Register the timer in the reactor with the new waker.
464
+ let id = Reactor :: get ( ) . insert_timer ( * when, cx. waker ( ) ) ;
465
+ this. id_and_waker = Some ( ( id, cx. waker ( ) . clone ( ) ) ) ;
466
+ }
467
+ Some ( _) => { }
395
468
}
396
- Some ( _) => { }
397
469
}
398
470
}
471
+
399
472
Poll :: Pending
400
473
}
401
474
}
0 commit comments