Skip to content

Commit d9dbefe

Browse files
author
chaoyuepan
committed
add atomic_waker
1 parent 13a7e2a commit d9dbefe

File tree

4 files changed

+68
-0
lines changed

4 files changed

+68
-0
lines changed

special/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ async-lock = "2.5.0"
1111
async-oneshot = "0.5.0"
1212
async-weighted-semaphore = "0.2.1"
1313
async_singleflight = "0.5.0"
14+
atomic-waker = "1.1.2"
1415
atomic_float = "0.1.0"
1516
atomicbox = "0.4.0"
1617
atomig = "0.4.0"

special/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ fn main() {
6161
sync_cow_example().unwrap();
6262
arc_swap_example();
6363

64+
atomic_waker_example();
6465
}
6566

6667

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
use futures::future::Future;
2+
use futures::task::{Context, Poll, AtomicWaker};
3+
use std::sync::Arc;
4+
use std::sync::atomic::AtomicBool;
5+
use std::sync::atomic::Ordering::Relaxed;
6+
use std::pin::Pin;
7+
8+
struct Inner {
9+
waker: AtomicWaker,
10+
set: AtomicBool,
11+
}
12+
13+
#[derive(Clone)]
14+
struct Flag(Arc<Inner>);
15+
16+
impl Flag {
17+
pub fn new() -> Self {
18+
Flag(Arc::new(Inner {
19+
waker: AtomicWaker::new(),
20+
set: AtomicBool::new(false),
21+
}))
22+
}
23+
24+
pub fn signal(&self) {
25+
self.0.set.store(true, Relaxed);
26+
self.0.waker.wake();
27+
}
28+
}
29+
30+
impl Future for Flag {
31+
type Output = bool;
32+
33+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<bool> {
34+
// quick check to avoid registration if already done.
35+
if self.0.set.load(Relaxed) {
36+
return Poll::Ready(true);
37+
}
38+
39+
self.0.waker.register(cx.waker());
40+
41+
// Need to check condition **after** `register` to avoid a race
42+
// condition that would result in lost notifications.
43+
if self.0.set.load(Relaxed) {
44+
Poll::Ready(true)
45+
} else {
46+
Poll::Pending
47+
}
48+
}
49+
}
50+
51+
pub fn atomic_waker_example() {
52+
smol::block_on(async {
53+
let flag = Flag::new();
54+
let flag2 = flag.clone();
55+
56+
smol::spawn(async move {
57+
smol::Timer::after(std::time::Duration::from_secs(1)).await;
58+
flag2.signal();
59+
})
60+
.detach();
61+
62+
println!("Waiting for flag: {}", flag.await);
63+
});
64+
}

special/src/primitive/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ mod async_lock_examples;
1212
mod atomic_examples;
1313
mod simple_mutex_examples;
1414
mod waitgroup_examples;
15+
mod atomic_waker_examples;
1516

1617
pub use try_lock_examples::*;
1718
pub use sharded_slab_example::*;
1819
pub use async_lock_examples::*;
1920
pub use atomic_examples::*;
2021
pub use simple_mutex_examples::*;
2122
pub use waitgroup_examples::*;
23+
pub use atomic_waker_examples::*;
2224

0 commit comments

Comments
 (0)