Skip to content

Commit c840b62

Browse files
committed
test: Add async tests
1 parent a3c45fb commit c840b62

File tree

4 files changed

+214
-131
lines changed

4 files changed

+214
-131
lines changed

Cargo.lock

Lines changed: 110 additions & 78 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ linux-raw-sys = { version = "0.11", default-features = false, features = [
2121
spin = { version = "0.10", default-features = false, features = ["spin_mutex"] }
2222

2323
[dev-dependencies]
24-
rand = "0.9"
24+
futures = "0.3"
25+
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] }

tests/async.rs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use std::{
2+
future::Future,
3+
pin::Pin,
4+
sync::{
5+
Arc,
6+
atomic::{AtomicBool, AtomicUsize, Ordering},
7+
},
8+
task::{Context, Poll},
9+
time::Duration,
10+
};
11+
12+
use axpoll::PollSet;
13+
use tokio::time;
14+
15+
struct WaitFuture {
16+
ps: Arc<PollSet>,
17+
ready: Arc<AtomicBool>,
18+
}
19+
20+
impl Future for WaitFuture {
21+
type Output = ();
22+
23+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
24+
if self.ready.load(Ordering::SeqCst) {
25+
return Poll::Ready(());
26+
} else {
27+
self.ps.register(cx.waker());
28+
return Poll::Pending;
29+
}
30+
}
31+
}
32+
33+
impl WaitFuture {
34+
fn new(ps: Arc<PollSet>, ready: Arc<AtomicBool>) -> Self {
35+
Self { ps, ready }
36+
}
37+
}
38+
39+
struct Counter(AtomicUsize);
40+
41+
impl Counter {
42+
fn new() -> Arc<Self> {
43+
Arc::new(Self(AtomicUsize::new(0)))
44+
}
45+
46+
fn count(&self) -> usize {
47+
self.0.load(Ordering::SeqCst)
48+
}
49+
50+
fn add(&self) {
51+
self.0.fetch_add(1, Ordering::SeqCst);
52+
}
53+
}
54+
55+
#[tokio::test]
56+
async fn async_wake_single() {
57+
let ps = Arc::new(PollSet::new());
58+
let ready = Arc::new(AtomicBool::new(false));
59+
60+
let f = WaitFuture::new(ps.clone(), ready.clone());
61+
62+
let handle = tokio::spawn(async move {
63+
ready.clone().store(true, Ordering::SeqCst);
64+
ps.clone().wake();
65+
});
66+
67+
f.await;
68+
handle.await.unwrap();
69+
}
70+
71+
#[tokio::test]
72+
async fn async_wake_many() {
73+
let ps = Arc::new(PollSet::new());
74+
let counter = Counter::new();
75+
76+
let mut flags = Vec::new();
77+
let mut handles = Vec::new();
78+
79+
for _ in 0..65 {
80+
let flag = Arc::new(AtomicBool::new(false));
81+
let f = WaitFuture::new(ps.clone(), flag.clone());
82+
let counter = counter.clone();
83+
let h = tokio::spawn(async move {
84+
f.await;
85+
counter.add();
86+
});
87+
flags.push(flag);
88+
handles.push(h);
89+
}
90+
91+
time::sleep(Duration::from_millis(20)).await;
92+
93+
for f in &flags {
94+
f.store(true, Ordering::SeqCst);
95+
}
96+
ps.wake();
97+
for h in handles {
98+
h.await.unwrap();
99+
}
100+
101+
assert_eq!(counter.count(), 65);
102+
}

0 commit comments

Comments
 (0)