fast/sync/
yield.rs

1use std::pin::pin;
2use std::sync::atomic::AtomicBool;
3use std::task::Poll::*;
4
5use crate::rt::worker::current_worker;
6use crate::rt::{poll, waker};
7use crate::{
8    rt::block_on,
9    time::{Duration, Instant, TimeUnit, wait_until},
10};
11
12pub struct Yield {
13    until: Instant,
14    ready: AtomicBool,
15}
16
17impl Yield {
18    pub fn new(until: Instant) -> Self {
19        Self {
20            until,
21            ready: AtomicBool::new(false),
22        }
23    }
24}
25
26impl Future for Yield {
27    type Output = ();
28
29    fn poll(
30        self: std::pin::Pin<&mut Self>,
31        cx: &mut std::task::Context<'_>,
32    ) -> std::task::Poll<Self::Output> {
33        let waker = cx.waker().clone();
34        poll(cx, async move {
35            if self.until > Instant::now() {
36                let waker = waker.clone();
37                wait_until(self.until, move || {
38                    dbg!("WOAHHHHHH");
39                    waker.wake_by_ref();
40                })
41                .await;
42            }
43
44            loop {
45                if self.ready.load(std::sync::atomic::Ordering::Relaxed) {
46                    return;
47                } else {
48                    self.ready.store(true, std::sync::atomic::Ordering::Relaxed);
49                }
50            }
51        })
52    }
53}
54
55pub fn yield_until(until: Instant) -> Yield {
56    Yield::new(until)
57}
58
59pub fn yield_for<T: TimeUnit>(duration: Duration<T>) -> Yield {
60    Yield::new(Instant::now() + duration)
61}
62
63pub fn yield_now() -> Yield {
64    Yield::new(Instant::now())
65}