use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
time::Duration,
};
use std::{task::Waker, time::Instant};
use crate::{executor::EXECUTOR, reactor::Sleeper};
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Sleep {
deadline: Instant,
registered_waker: Option<Waker>,
}
impl Future for Sleep {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
if Instant::now() >= self.deadline {
return Poll::Ready(());
}
if self
.registered_waker
.as_ref()
.map(|w| !w.will_wake(cx.waker()))
.unwrap_or(true)
{
let this = self.get_mut();
this.registered_waker = Some(cx.waker().clone());
EXECUTOR.with(|ex| {
ex.with_reactor(|reactor| {
reactor.sleepers.push(Sleeper {
deadline: this.deadline,
waker: cx.waker().clone(),
});
});
});
}
Poll::Pending
}
}
pub fn sleep(duration: Duration) -> Sleep {
Sleep {
deadline: Instant::now() + duration,
registered_waker: None,
}
}
pub const fn sleep_until(deadline: Instant) -> Sleep {
Sleep {
deadline,
registered_waker: None,
}
}