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    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
36        match &self.state {
37            State::Idle => {
38                let deadline = self.deadline;
39
40                let waker = cx.waker().clone();
41
42                let join_handle = thread::spawn(move || {
43                    thread::sleep(deadline.saturating_duration_since(Instant::now()));
44
45                    waker.wake();
46                });
47
48                self.state = State::Spawned(join_handle);
49
50                Poll::Pending
51            },
52            State::Spawned(join_handle) => {
53                if join_handle.is_finished() {
54                    self.state = State::Completed;
55
56                    Poll::Ready(())
57                } else {
58                    Poll::Pending
59                }
60            },
61            State::Completed => Poll::Ready(()),
62        }
63    }
64}
65
66fn main() -> result::Result<(), Box<dyn error::Error>> {
67    Executor::block_on(async {
68        Timer::new(Duration::from_secs(5)).await;
69
70        println!("Hello, world!");
71
72        Ok::<(), Box<dyn error::Error>>(())
73    })?;
74
75    Ok(())
76}