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}