use std::future::Future;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll, Waker};
use std::time::Duration;
#[derive(Debug, Default)]
struct SleepState {
done: bool,
waker: Option<Waker>,
}
#[derive(Debug)]
pub(crate) struct ThreadSleep {
shared: Arc<Mutex<SleepState>>,
}
pub(crate) fn sleep(dur: Duration) -> ThreadSleep {
let shared = Arc::new(Mutex::new(SleepState::default()));
let thread_shared = Arc::clone(&shared);
std::thread::spawn(move || {
std::thread::sleep(dur);
let mut st = thread_shared.lock().unwrap_or_else(|e| e.into_inner());
st.done = true;
if let Some(waker) = st.waker.take() {
waker.wake();
}
});
ThreadSleep { shared }
}
impl Future for ThreadSleep {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
let mut st = self.shared.lock().unwrap_or_else(|e| e.into_inner());
if st.done {
Poll::Ready(())
} else {
st.waker = Some(cx.waker().clone());
Poll::Pending
}
}
}