1 use crate::time::driver::Registration;
2 use crate::time::{Duration, Instant};
3
4 use std::future::Future;
5 use std::pin::Pin;
6 use std::task::{self, Poll};
7
8 /// Waits until `deadline` is reached.
9 ///
10 /// No work is performed while awaiting on the delay to complete. The delay
11 /// operates at millisecond granularity and should not be used for tasks that
12 /// require high-resolution timers.
13 ///
14 /// # Cancellation
15 ///
16 /// Canceling a delay is done by dropping the returned future. No additional
17 /// cleanup work is required.
delay_until(deadline: Instant) -> Delay18 pub fn delay_until(deadline: Instant) -> Delay {
19 let registration = Registration::new(deadline, Duration::from_millis(0));
20 Delay { registration }
21 }
22
23 /// Waits until `duration` has elapsed.
24 ///
25 /// Equivalent to `delay_until(Instant::now() + duration)`. An asynchronous
26 /// analog to `std::thread::sleep`.
27 ///
28 /// No work is performed while awaiting on the delay to complete. The delay
29 /// operates at millisecond granularity and should not be used for tasks that
30 /// require high-resolution timers.
31 ///
32 /// To run something regularly on a schedule, see [`interval`].
33 ///
34 /// # Cancellation
35 ///
36 /// Canceling a delay is done by dropping the returned future. No additional
37 /// cleanup work is required.
38 ///
39 /// # Examples
40 ///
41 /// Wait 100ms and print "100 ms have elapsed".
42 ///
43 /// ```
44 /// use tokio::time::{delay_for, Duration};
45 ///
46 /// #[tokio::main]
47 /// async fn main() {
48 /// delay_for(Duration::from_millis(100)).await;
49 /// println!("100 ms have elapsed");
50 /// }
51 /// ```
52 ///
53 /// [`interval`]: crate::time::interval()
54 #[cfg_attr(docsrs, doc(alias = "sleep"))]
delay_for(duration: Duration) -> Delay55 pub fn delay_for(duration: Duration) -> Delay {
56 delay_until(Instant::now() + duration)
57 }
58
59 /// Future returned by [`delay_until`](delay_until) and
60 /// [`delay_for`](delay_for).
61 #[derive(Debug)]
62 #[must_use = "futures do nothing unless you `.await` or poll them"]
63 pub struct Delay {
64 /// The link between the `Delay` instance and the timer that drives it.
65 ///
66 /// This also stores the `deadline` value.
67 registration: Registration,
68 }
69
70 impl Delay {
new_timeout(deadline: Instant, duration: Duration) -> Delay71 pub(crate) fn new_timeout(deadline: Instant, duration: Duration) -> Delay {
72 let registration = Registration::new(deadline, duration);
73 Delay { registration }
74 }
75
76 /// Returns the instant at which the future will complete.
deadline(&self) -> Instant77 pub fn deadline(&self) -> Instant {
78 self.registration.deadline()
79 }
80
81 /// Returns `true` if the `Delay` has elapsed
82 ///
83 /// A `Delay` is elapsed when the requested duration has elapsed.
is_elapsed(&self) -> bool84 pub fn is_elapsed(&self) -> bool {
85 self.registration.is_elapsed()
86 }
87
88 /// Resets the `Delay` instance to a new deadline.
89 ///
90 /// Calling this function allows changing the instant at which the `Delay`
91 /// future completes without having to create new associated state.
92 ///
93 /// This function can be called both before and after the future has
94 /// completed.
reset(&mut self, deadline: Instant)95 pub fn reset(&mut self, deadline: Instant) {
96 self.registration.reset(deadline);
97 }
98 }
99
100 impl Future for Delay {
101 type Output = ();
102
poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output>103 fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> {
104 // `poll_elapsed` can return an error in two cases:
105 //
106 // - AtCapacity: this is a pathlogical case where far too many
107 // delays have been scheduled.
108 // - Shutdown: No timer has been setup, which is a mis-use error.
109 //
110 // Both cases are extremely rare, and pretty accurately fit into
111 // "logic errors", so we just panic in this case. A user couldn't
112 // really do much better if we passed the error onwards.
113 match ready!(self.registration.poll_elapsed(cx)) {
114 Ok(()) => Poll::Ready(()),
115 Err(e) => panic!("timer error: {}", e),
116 }
117 }
118 }
119