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