use futures::executor::block_on; use futures::future::poll_fn; use futures::task::{AtomicWaker, Poll}; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; use std::sync::Arc; use std::thread; #[test] fn basic() { let atomic_waker = Arc::new(AtomicWaker::new()); let atomic_waker_copy = atomic_waker.clone(); let returned_pending = Arc::new(AtomicUsize::new(0)); let returned_pending_copy = returned_pending.clone(); let woken = Arc::new(AtomicUsize::new(0)); let woken_copy = woken.clone(); let t = thread::spawn(move || { let mut pending_count = 0; block_on(poll_fn(move |cx| { if woken_copy.load(Ordering::Relaxed) == 1 { Poll::Ready(()) } else { // Assert we return pending exactly once assert_eq!(0, pending_count); pending_count += 1; atomic_waker_copy.register(cx.waker()); returned_pending_copy.store(1, Ordering::Relaxed); Poll::Pending } })) }); while returned_pending.load(Ordering::Relaxed) == 0 {} // give spawned thread some time to sleep in `block_on` thread::yield_now(); woken.store(1, Ordering::Relaxed); atomic_waker.wake(); t.join().unwrap(); }