Skip to content

Commit d1020da

Browse files
stepanchegcramertj
authored andcommitted
AtomicWaker test
1 parent 8157b0a commit d1020da

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

futures-util/tests/atomic_waker.rs

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

0 commit comments

Comments
 (0)