File tree Expand file tree Collapse file tree 4 files changed +68
-0
lines changed Expand file tree Collapse file tree 4 files changed +68
-0
lines changed Original file line number Diff line number Diff line change @@ -11,6 +11,7 @@ async-lock = "2.5.0"
1111async-oneshot = " 0.5.0"
1212async-weighted-semaphore = " 0.2.1"
1313async_singleflight = " 0.5.0"
14+ atomic-waker = " 1.1.2"
1415atomic_float = " 0.1.0"
1516atomicbox = " 0.4.0"
1617atomig = " 0.4.0"
Original file line number Diff line number Diff 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
Original file line number Diff line number Diff line change 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+ }
Original file line number Diff line number Diff line change @@ -12,11 +12,13 @@ mod async_lock_examples;
1212mod atomic_examples;
1313mod simple_mutex_examples;
1414mod waitgroup_examples;
15+ mod atomic_waker_examples;
1516
1617pub use try_lock_examples:: * ;
1718pub use sharded_slab_example:: * ;
1819pub use async_lock_examples:: * ;
1920pub use atomic_examples:: * ;
2021pub use simple_mutex_examples:: * ;
2122pub use waitgroup_examples:: * ;
23+ pub use atomic_waker_examples:: * ;
2224
You can’t perform that action at this time.
0 commit comments