Skip to main content

timer/
timer.rs

1use std::{
2    error,
3    pin::Pin,
4    result,
5    task::{Context, Poll},
6    thread::{self, JoinHandle},
7    time::{Duration, Instant},
8};
9
10use traffic_light::executor::Executor;
11
12enum State {
13    Idle,
14    Spawned(JoinHandle<()>),
15    Completed,
16}
17
18pub struct Timer {
19    state: State,
20    deadline: Instant,
21}
22
23impl Timer {
24    pub fn new(duration: Duration) -> Self {
25        Self {
26            state: State::Idle,
27            deadline: (Instant::now() + duration),
28        }
29    }
30}
31
32impl Future for Timer {
33    type Output = ();
34
35    #[rustfmt::skip]
36    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
37        match &self.state {
38            State::Idle => {
39                let deadline = self.deadline;
40
41                let waker = cx.waker().clone();
42
43                let join_handle = thread::spawn(move || {
44                    thread::sleep(deadline.saturating_duration_since(Instant::now()));
45
46                    waker.wake();
47                });
48
49                self.state = State::Spawned(join_handle);
50
51                Poll::Pending
52            },
53            State::Spawned(join_handle) => {
54                if join_handle.is_finished() {
55                    self.state = State::Completed;
56
57                    Poll::Ready(())
58                } else {
59                    Poll::Pending
60                }
61            },
62            State::Completed => Poll::Ready(()),
63        }
64    }
65}
66
67fn main() -> result::Result<(), Box<dyn error::Error>> {
68    Executor::block_on(async {
69        Timer::new(Duration::from_secs(5)).await;
70
71        println!("Hello, world!");
72
73        Ok::<(), Box<dyn error::Error>>(())
74    })?;
75
76    Ok(())
77}