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}