1use super::waiter::{Token, Waiter};
2use super::{now, WAITS, WAITS_NUM};
3use core::future::Future;
4use core::pin::Pin;
5use core::task::{Context, Poll};
6use core::time::Duration;
7
8pub fn sleep(duration: Duration) -> Sleep {
9 let deadline = now() + duration.as_nanos() as u64;
10 Sleep {
11 pool: &WAITS,
12 deadline,
13 token: None,
14 }
15}
16pub fn sleep_until(deadline: u64) -> Sleep {
17 Sleep {
18 pool: &WAITS,
19 deadline,
20 token: None,
21 }
22}
23
24pub struct Sleep {
25 pool: &'static Waiter<WAITS_NUM>,
26 deadline: u64,
27 token: Option<Token<'static, WAITS_NUM>>,
28}
29impl Future for Sleep {
30 type Output = ();
31 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
32 let deadline = self.deadline;
33 if deadline < now() {
34 return Poll::Ready(());
35 }
36 let waker = cx.waker();
37 if let Some(token) = &self.token {
38 token.swap(waker.clone(), deadline);
39 } else if let Ok(token) = self.pool.register() {
40 token.swap(waker.clone(), deadline);
41 self.token = Some(token);
42 } else {
43 waker.wake_by_ref();
44 }
45 if deadline < now() {
46 Poll::Ready(())
47 } else {
48 Poll::Pending
49 }
50 }
51}