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
use crate::time::driver::Registration; use crate::time::{Duration, Instant}; use std::future::Future; use std::pin::Pin; use std::task::{self, Poll}; /// Waits until `deadline` is reached. /// /// No work is performed while awaiting on the delay to complete. The delay /// operates at millisecond granularity and should not be used for tasks that /// require high-resolution timers. /// /// # Cancellation /// /// Canceling a delay is done by dropping the returned future. No additional /// cleanup work is required. pub fn delay_until(deadline: Instant) -> Delay { let registration = Registration::new(deadline, Duration::from_millis(0)); Delay { registration } } /// Waits until `duration` has elapsed. /// /// Equivalent to `delay_until(Instant::now() + duration)`. An asynchronous /// analog to `std::thread::sleep`. /// /// No work is performed while awaiting on the delay to complete. The delay /// operates at millisecond granularity and should not be used for tasks that /// require high-resolution timers. /// /// To run something regularly on a schedule, see [`interval`]. /// /// # Cancellation /// /// Canceling a delay is done by dropping the returned future. No additional /// cleanup work is required. /// /// # Examples /// /// Wait 100ms and print "100 ms have elapsed". /// /// ``` /// use tokio::time::{delay_for, Duration}; /// /// #[tokio::main] /// async fn main() { /// delay_for(Duration::from_millis(100)).await; /// println!("100 ms have elapsed"); /// } /// ``` /// /// [`interval`]: crate::time::interval() #[cfg_attr(docsrs, doc(alias = "sleep"))] pub fn delay_for(duration: Duration) -> Delay { delay_until(Instant::now() + duration) } /// Future returned by [`delay_until`](delay_until) and /// [`delay_for`](delay_for). #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct Delay { /// The link between the `Delay` instance and the timer that drives it. /// /// This also stores the `deadline` value. registration: Registration, } impl Delay { pub(crate) fn new_timeout(deadline: Instant, duration: Duration) -> Delay { let registration = Registration::new(deadline, duration); Delay { registration } } /// Returns the instant at which the future will complete. pub fn deadline(&self) -> Instant { self.registration.deadline() } /// Returns `true` if the `Delay` has elapsed /// /// A `Delay` is elapsed when the requested duration has elapsed. pub fn is_elapsed(&self) -> bool { self.registration.is_elapsed() } /// Resets the `Delay` instance to a new deadline. /// /// Calling this function allows changing the instant at which the `Delay` /// future completes without having to create new associated state. /// /// This function can be called both before and after the future has /// completed. pub fn reset(&mut self, deadline: Instant) { self.registration.reset(deadline); } } impl Future for Delay { type Output = (); fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll<Self::Output> { // `poll_elapsed` can return an error in two cases: // // - AtCapacity: this is a pathlogical case where far too many // delays have been scheduled. // - Shutdown: No timer has been setup, which is a mis-use error. // // Both cases are extremely rare, and pretty accurately fit into // "logic errors", so we just panic in this case. A user couldn't // really do much better if we passed the error onwards. match ready!(self.registration.poll_elapsed(cx)) { Ok(()) => Poll::Ready(()), Err(e) => panic!("timer error: {}", e), } } }