1use std::{
2 cmp::Reverse,
3 pin::Pin,
4 sync::{Mutex, MutexGuard},
5 task::{Context, Poll, Waker},
6 time::{Duration, Instant},
7};
8
9use futures::Future;
10
11use crate::context;
12
13#[derive(Default)]
14pub(crate) struct Queue(Mutex<Vec<(Instant, Waker)>>);
15impl Queue {
16 pub fn insert(&self, instant: Instant, task: Waker) {
17 let mut queue = self.0.lock().unwrap();
18 let index = match queue.binary_search_by_key(&Reverse(instant), |e| Reverse(e.0)) {
19 Ok(index) | Err(index) => index,
20 };
21 queue.insert(index, (instant, task));
22 }
23}
24
25impl<'a> IntoIterator for &'a Queue {
26 type Item = Waker;
27 type IntoIter = QueueIter<'a>;
28
29 fn into_iter(self) -> Self::IntoIter {
30 QueueIter(self.0.lock().unwrap(), Instant::now())
31 }
32}
33
34pub(crate) struct QueueIter<'a>(MutexGuard<'a, Vec<(Instant, Waker)>>, Instant);
35impl Iterator for QueueIter<'_> {
36 type Item = Waker;
37
38 fn next(&mut self) -> Option<Self::Item> {
39 let (time, task) = self.0.pop()?;
40 if time > self.1 {
41 self.0.push((time, task));
42 None
43 } else {
44 Some(task)
45 }
46 }
47}
48
49pub struct Sleep {
52 instant: Instant,
53}
54
55impl Unpin for Sleep {}
56
57impl Future for Sleep {
58 type Output = ();
59
60 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
61 if self.instant > Instant::now() {
63 context(|r| r.timers.insert(self.instant, cx.waker().clone()));
64 Poll::Pending
65 } else {
66 Poll::Ready(())
67 }
68 }
69}
70
71impl Sleep {
72 #[must_use]
74 pub fn until(instant: Instant) -> Sleep {
75 Self { instant }
76 }
77 #[must_use]
79 pub fn duration(duration: Duration) -> Sleep {
80 Sleep::until(Instant::now() + duration)
81 }
82}