1 #[test] basic()2fn basic() { 3 use std::sync::atomic::AtomicUsize; 4 use std::sync::atomic::Ordering; 5 use std::sync::Arc; 6 use std::thread; 7 8 use futures::executor::block_on; 9 use futures::future::poll_fn; 10 use futures::task::{AtomicWaker, Poll}; 11 12 let atomic_waker = Arc::new(AtomicWaker::new()); 13 let atomic_waker_copy = atomic_waker.clone(); 14 15 let returned_pending = Arc::new(AtomicUsize::new(0)); 16 let returned_pending_copy = returned_pending.clone(); 17 18 let woken = Arc::new(AtomicUsize::new(0)); 19 let woken_copy = woken.clone(); 20 21 let t = thread::spawn(move || { 22 let mut pending_count = 0; 23 24 block_on(poll_fn(move |cx| { 25 if woken_copy.load(Ordering::Relaxed) == 1 { 26 Poll::Ready(()) 27 } else { 28 // Assert we return pending exactly once 29 assert_eq!(0, pending_count); 30 pending_count += 1; 31 atomic_waker_copy.register(cx.waker()); 32 33 returned_pending_copy.store(1, Ordering::Relaxed); 34 35 Poll::Pending 36 } 37 })) 38 }); 39 40 while returned_pending.load(Ordering::Relaxed) == 0 {} 41 42 // give spawned thread some time to sleep in `block_on` 43 thread::yield_now(); 44 45 woken.store(1, Ordering::Relaxed); 46 atomic_waker.wake(); 47 48 t.join().unwrap(); 49 } 50