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