@@ -56,25 +56,33 @@ impl Notifier {
56
56
/// Gets a [`Future`] that will get woken up with any waiters
57
57
pub ( crate ) fn get_future ( & self ) -> Future {
58
58
let mut lock = self . notify_pending . lock ( ) . unwrap ( ) ;
59
+ let mut self_idx = 0 ;
59
60
if let Some ( existing_state) = & lock. 1 {
60
- if existing_state. lock ( ) . unwrap ( ) . callbacks_made {
61
+ let mut locked = existing_state. lock ( ) . unwrap ( ) ;
62
+ if locked. callbacks_made {
61
63
// If the existing `FutureState` has completed and actually made callbacks,
62
64
// consider the notification flag to have been cleared and reset the future state.
65
+ mem:: drop ( locked) ;
63
66
lock. 1 . take ( ) ;
64
67
lock. 0 = false ;
68
+ } else {
69
+ self_idx = locked. next_idx ;
70
+ locked. next_idx += 1 ;
65
71
}
66
72
}
67
73
if let Some ( existing_state) = & lock. 1 {
68
- Future { state : Arc :: clone ( & existing_state) }
74
+ Future { state : Arc :: clone ( & existing_state) , self_idx }
69
75
} else {
70
76
let state = Arc :: new ( Mutex :: new ( FutureState {
71
77
callbacks : Vec :: new ( ) ,
78
+ std_future_callbacks : Vec :: new ( ) ,
72
79
callbacks_with_state : Vec :: new ( ) ,
73
80
complete : lock. 0 ,
74
81
callbacks_made : false ,
82
+ next_idx : 1 ,
75
83
} ) ) ;
76
84
lock. 1 = Some ( Arc :: clone ( & state) ) ;
77
- Future { state }
85
+ Future { state, self_idx : 0 }
78
86
}
79
87
}
80
88
@@ -109,36 +117,39 @@ define_callback!(Send);
109
117
define_callback ! ( ) ;
110
118
111
119
pub ( crate ) struct FutureState {
112
- // When we're tracking whether a callback counts as having woken the user's code, we check the
113
- // first bool - set to false if we're just calling a Waker, and true if we're calling an actual
114
- // user-provided function.
115
- callbacks : Vec < ( bool , Box < dyn FutureCallback > ) > ,
116
- callbacks_with_state : Vec < ( bool , Box < dyn Fn ( & Arc < Mutex < FutureState > > ) -> ( ) + Send > ) > ,
120
+ // `callbacks` count as having woken the users' code (as they go direct to the user), but
121
+ // `std_future_callbacks` and `callbacks_with_state` do not (as the first just wakes a future,
122
+ // we only count it after another `poll()` and the second wakes a `Sleeper` which handles
123
+ // setting `callbacks_made` itself).
124
+ callbacks : Vec < Box < dyn FutureCallback > > ,
125
+ std_future_callbacks : Vec < ( usize , StdWaker ) > ,
126
+ callbacks_with_state : Vec < Box < dyn Fn ( & Arc < Mutex < FutureState > > ) -> ( ) + Send > > ,
117
127
complete : bool ,
118
128
callbacks_made : bool ,
129
+ next_idx : usize ,
119
130
}
120
131
121
132
fn complete_future ( this : & Arc < Mutex < FutureState > > ) -> bool {
122
133
let mut state_lock = this. lock ( ) . unwrap ( ) ;
123
134
let state = & mut * state_lock;
124
- for ( counts_as_call , callback) in state. callbacks . drain ( ..) {
135
+ for callback in state. callbacks . drain ( ..) {
125
136
callback. call ( ) ;
126
- state. callbacks_made |= counts_as_call ;
137
+ state. callbacks_made = true ;
127
138
}
128
- for ( counts_as_call, callback) in state. callbacks_with_state . drain ( ..) {
139
+ for ( _, waker) in state. std_future_callbacks . drain ( ..) {
140
+ waker. 0 . wake_by_ref ( ) ;
141
+ }
142
+ for callback in state. callbacks_with_state . drain ( ..) {
129
143
( callback) ( this) ;
130
- state. callbacks_made |= counts_as_call;
131
144
}
132
145
state. complete = true ;
133
146
state. callbacks_made
134
147
}
135
148
136
149
/// A simple future which can complete once, and calls some callback(s) when it does so.
137
- ///
138
- /// Clones can be made and all futures cloned from the same source will complete at the same time.
139
- #[ derive( Clone ) ]
140
150
pub struct Future {
141
151
state : Arc < Mutex < FutureState > > ,
152
+ self_idx : usize ,
142
153
}
143
154
144
155
impl Future {
@@ -153,7 +164,7 @@ impl Future {
153
164
mem:: drop ( state) ;
154
165
callback. call ( ) ;
155
166
} else {
156
- state. callbacks . push ( ( true , callback) ) ;
167
+ state. callbacks . push ( callback) ;
157
168
}
158
169
}
159
170
@@ -169,16 +180,16 @@ impl Future {
169
180
170
181
/// Waits until this [`Future`] completes.
171
182
#[ cfg( feature = "std" ) ]
172
- pub fn wait ( self ) {
173
- Sleeper :: from_single_future ( self ) . wait ( ) ;
183
+ pub fn wait ( & self ) {
184
+ Sleeper :: from_single_future ( & self ) . wait ( ) ;
174
185
}
175
186
176
187
/// Waits until this [`Future`] completes or the given amount of time has elapsed.
177
188
///
178
189
/// Returns true if the [`Future`] completed, false if the time elapsed.
179
190
#[ cfg( feature = "std" ) ]
180
- pub fn wait_timeout ( self , max_wait : Duration ) -> bool {
181
- Sleeper :: from_single_future ( self ) . wait_timeout ( max_wait)
191
+ pub fn wait_timeout ( & self , max_wait : Duration ) -> bool {
192
+ Sleeper :: from_single_future ( & self ) . wait_timeout ( max_wait)
182
193
}
183
194
184
195
#[ cfg( test) ]
@@ -191,11 +202,14 @@ impl Future {
191
202
}
192
203
}
193
204
205
+ impl Drop for Future {
206
+ fn drop ( & mut self ) {
207
+ self . state . lock ( ) . unwrap ( ) . std_future_callbacks . retain ( |( idx, _) | * idx != self . self_idx ) ;
208
+ }
209
+ }
210
+
194
211
use core:: task:: Waker ;
195
212
struct StdWaker ( pub Waker ) ;
196
- impl FutureCallback for StdWaker {
197
- fn call ( & self ) { self . 0 . wake_by_ref ( ) }
198
- }
199
213
200
214
/// This is not exported to bindings users as Rust Futures aren't usable in language bindings.
201
215
impl < ' a > StdFuture for Future {
@@ -208,7 +222,8 @@ impl<'a> StdFuture for Future {
208
222
Poll :: Ready ( ( ) )
209
223
} else {
210
224
let waker = cx. waker ( ) . clone ( ) ;
211
- state. callbacks . push ( ( false , Box :: new ( StdWaker ( waker) ) ) ) ;
225
+ state. std_future_callbacks . retain ( |( idx, _) | * idx != self . self_idx ) ;
226
+ state. std_future_callbacks . push ( ( self . self_idx , StdWaker ( waker) ) ) ;
212
227
Poll :: Pending
213
228
}
214
229
}
@@ -224,17 +239,17 @@ pub struct Sleeper {
224
239
#[ cfg( feature = "std" ) ]
225
240
impl Sleeper {
226
241
/// Constructs a new sleeper from one future, allowing blocking on it.
227
- pub fn from_single_future ( future : Future ) -> Self {
228
- Self { notifiers : vec ! [ future. state] }
242
+ pub fn from_single_future ( future : & Future ) -> Self {
243
+ Self { notifiers : vec ! [ Arc :: clone ( & future. state) ] }
229
244
}
230
245
/// Constructs a new sleeper from two futures, allowing blocking on both at once.
231
246
// Note that this is the common case - a ChannelManager and ChainMonitor.
232
- pub fn from_two_futures ( fut_a : Future , fut_b : Future ) -> Self {
233
- Self { notifiers : vec ! [ fut_a. state, fut_b. state] }
247
+ pub fn from_two_futures ( fut_a : & Future , fut_b : & Future ) -> Self {
248
+ Self { notifiers : vec ! [ Arc :: clone ( & fut_a. state) , Arc :: clone ( & fut_b. state) ] }
234
249
}
235
250
/// Constructs a new sleeper on many futures, allowing blocking on all at once.
236
251
pub fn new ( futures : Vec < Future > ) -> Self {
237
- Self { notifiers : futures. into_iter ( ) . map ( |f| f. state ) . collect ( ) }
252
+ Self { notifiers : futures. into_iter ( ) . map ( |f| Arc :: clone ( & f. state ) ) . collect ( ) }
238
253
}
239
254
/// Prepares to go into a wait loop body, creating a condition variable which we can block on
240
255
/// and an `Arc<Mutex<Option<_>>>` which gets set to the waking `Future`'s state prior to the
@@ -251,10 +266,10 @@ impl Sleeper {
251
266
* notified_fut_mtx. lock ( ) . unwrap ( ) = Some ( Arc :: clone ( & notifier_mtx) ) ;
252
267
break ;
253
268
}
254
- notifier. callbacks_with_state . push ( ( false , Box :: new ( move |notifier_ref| {
269
+ notifier. callbacks_with_state . push ( Box :: new ( move |notifier_ref| {
255
270
* notified_fut_ref. lock ( ) . unwrap ( ) = Some ( Arc :: clone ( notifier_ref) ) ;
256
271
cv_ref. notify_all ( ) ;
257
- } ) ) ) ;
272
+ } ) ) ;
258
273
}
259
274
}
260
275
( cv, notified_fut_mtx)
@@ -439,13 +454,15 @@ mod tests {
439
454
440
455
// Wait on the other thread to finish its sleep, note that the leak only happened if we
441
456
// actually have to sleep here, not if we immediately return.
442
- Sleeper :: from_two_futures ( future_a, future_b) . wait ( ) ;
457
+ Sleeper :: from_two_futures ( & future_a, & future_b) . wait ( ) ;
443
458
444
459
join_handle. join ( ) . unwrap ( ) ;
445
460
446
461
// then drop the notifiers and make sure the future states are gone.
447
462
mem:: drop ( notifier_a) ;
448
463
mem:: drop ( notifier_b) ;
464
+ mem:: drop ( future_a) ;
465
+ mem:: drop ( future_b) ;
449
466
450
467
assert ! ( future_state_a. upgrade( ) . is_none( ) && future_state_b. upgrade( ) . is_none( ) ) ;
451
468
}
@@ -455,10 +472,13 @@ mod tests {
455
472
let future = Future {
456
473
state : Arc :: new ( Mutex :: new ( FutureState {
457
474
callbacks : Vec :: new ( ) ,
475
+ std_future_callbacks : Vec :: new ( ) ,
458
476
callbacks_with_state : Vec :: new ( ) ,
459
477
complete : false ,
460
478
callbacks_made : false ,
461
- } ) )
479
+ next_idx : 1 ,
480
+ } ) ) ,
481
+ self_idx : 0 ,
462
482
} ;
463
483
let callback = Arc :: new ( AtomicBool :: new ( false ) ) ;
464
484
let callback_ref = Arc :: clone ( & callback) ;
@@ -475,10 +495,13 @@ mod tests {
475
495
let future = Future {
476
496
state : Arc :: new ( Mutex :: new ( FutureState {
477
497
callbacks : Vec :: new ( ) ,
498
+ std_future_callbacks : Vec :: new ( ) ,
478
499
callbacks_with_state : Vec :: new ( ) ,
479
500
complete : false ,
480
501
callbacks_made : false ,
481
- } ) )
502
+ next_idx : 1 ,
503
+ } ) ) ,
504
+ self_idx : 0 ,
482
505
} ;
483
506
complete_future ( & future. state ) ;
484
507
@@ -514,12 +537,15 @@ mod tests {
514
537
let mut future = Future {
515
538
state : Arc :: new ( Mutex :: new ( FutureState {
516
539
callbacks : Vec :: new ( ) ,
540
+ std_future_callbacks : Vec :: new ( ) ,
517
541
callbacks_with_state : Vec :: new ( ) ,
518
542
complete : false ,
519
543
callbacks_made : false ,
520
- } ) )
544
+ next_idx : 2 ,
545
+ } ) ) ,
546
+ self_idx : 0 ,
521
547
} ;
522
- let mut second_future = Future { state : Arc :: clone ( & future. state ) } ;
548
+ let mut second_future = Future { state : Arc :: clone ( & future. state ) , self_idx : 1 } ;
523
549
524
550
let ( woken, waker) = create_waker ( ) ;
525
551
assert_eq ! ( Pin :: new( & mut future) . poll( & mut Context :: from_waker( & waker) ) , Poll :: Pending ) ;
@@ -638,18 +664,18 @@ mod tests {
638
664
// Set both notifiers as woken without sleeping yet.
639
665
notifier_a. notify ( ) ;
640
666
notifier_b. notify ( ) ;
641
- Sleeper :: from_two_futures ( notifier_a. get_future ( ) , notifier_b. get_future ( ) ) . wait ( ) ;
667
+ Sleeper :: from_two_futures ( & notifier_a. get_future ( ) , & notifier_b. get_future ( ) ) . wait ( ) ;
642
668
643
669
// One future has woken us up, but the other should still have a pending notification.
644
- Sleeper :: from_two_futures ( notifier_a. get_future ( ) , notifier_b. get_future ( ) ) . wait ( ) ;
670
+ Sleeper :: from_two_futures ( & notifier_a. get_future ( ) , & notifier_b. get_future ( ) ) . wait ( ) ;
645
671
646
672
// However once we've slept twice, we should no longer have any pending notifications
647
- assert ! ( !Sleeper :: from_two_futures( notifier_a. get_future( ) , notifier_b. get_future( ) )
673
+ assert ! ( !Sleeper :: from_two_futures( & notifier_a. get_future( ) , & notifier_b. get_future( ) )
648
674
. wait_timeout( Duration :: from_millis( 10 ) ) ) ;
649
675
650
676
// Test ordering somewhat more.
651
677
notifier_a. notify ( ) ;
652
- Sleeper :: from_two_futures ( notifier_a. get_future ( ) , notifier_b. get_future ( ) ) . wait ( ) ;
678
+ Sleeper :: from_two_futures ( & notifier_a. get_future ( ) , & notifier_b. get_future ( ) ) . wait ( ) ;
653
679
}
654
680
655
681
#[ test]
@@ -667,7 +693,7 @@ mod tests {
667
693
668
694
// After sleeping one future (not guaranteed which one, however) will have its notification
669
695
// bit cleared.
670
- Sleeper :: from_two_futures ( notifier_a. get_future ( ) , notifier_b. get_future ( ) ) . wait ( ) ;
696
+ Sleeper :: from_two_futures ( & notifier_a. get_future ( ) , & notifier_b. get_future ( ) ) . wait ( ) ;
671
697
672
698
// By registering a callback on the futures for both notifiers, one will complete
673
699
// immediately, but one will remain tied to the notifier, and will complete once the
@@ -686,8 +712,48 @@ mod tests {
686
712
notifier_b. notify ( ) ;
687
713
688
714
assert ! ( callback_a. load( Ordering :: SeqCst ) && callback_b. load( Ordering :: SeqCst ) ) ;
689
- Sleeper :: from_two_futures ( notifier_a. get_future ( ) , notifier_b. get_future ( ) ) . wait ( ) ;
690
- assert ! ( !Sleeper :: from_two_futures( notifier_a. get_future( ) , notifier_b. get_future( ) )
715
+ Sleeper :: from_two_futures ( & notifier_a. get_future ( ) , & notifier_b. get_future ( ) ) . wait ( ) ;
716
+ assert ! ( !Sleeper :: from_two_futures( & notifier_a. get_future( ) , & notifier_b. get_future( ) )
691
717
. wait_timeout( Duration :: from_millis( 10 ) ) ) ;
692
718
}
719
+
720
+ #[ test]
721
+ #[ cfg( feature = "std" ) ]
722
+ fn multi_poll_stores_single_waker ( ) {
723
+ // When a `Future` is `poll()`ed multiple times, only the last `Waker` should be called,
724
+ // but previously we'd store all `Waker`s until they're all woken at once. This tests a few
725
+ // cases to ensure `Future`s avoid storing an endless set of `Waker`s.
726
+ let notifier = Notifier :: new ( ) ;
727
+ let future_state = Arc :: clone ( & notifier. get_future ( ) . state ) ;
728
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 0 ) ;
729
+
730
+ // Test that simply polling a future twice doesn't result in two pending `Waker`s.
731
+ let mut future_a = notifier. get_future ( ) ;
732
+ assert_eq ! ( Pin :: new( & mut future_a) . poll( & mut Context :: from_waker( & create_waker( ) . 1 ) ) , Poll :: Pending ) ;
733
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 1 ) ;
734
+ assert_eq ! ( Pin :: new( & mut future_a) . poll( & mut Context :: from_waker( & create_waker( ) . 1 ) ) , Poll :: Pending ) ;
735
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 1 ) ;
736
+
737
+ // If we poll a second future, however, that will store a second `Waker`.
738
+ let mut future_b = notifier. get_future ( ) ;
739
+ assert_eq ! ( Pin :: new( & mut future_b) . poll( & mut Context :: from_waker( & create_waker( ) . 1 ) ) , Poll :: Pending ) ;
740
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 2 ) ;
741
+
742
+ // but when we drop the `Future`s, the pending Wakers will also be dropped.
743
+ mem:: drop ( future_a) ;
744
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 1 ) ;
745
+ mem:: drop ( future_b) ;
746
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 0 ) ;
747
+
748
+ // Further, after polling a future twice, if the notifier is woken all Wakers are dropped.
749
+ let mut future_a = notifier. get_future ( ) ;
750
+ assert_eq ! ( Pin :: new( & mut future_a) . poll( & mut Context :: from_waker( & create_waker( ) . 1 ) ) , Poll :: Pending ) ;
751
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 1 ) ;
752
+ assert_eq ! ( Pin :: new( & mut future_a) . poll( & mut Context :: from_waker( & create_waker( ) . 1 ) ) , Poll :: Pending ) ;
753
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 1 ) ;
754
+ notifier. notify ( ) ;
755
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 0 ) ;
756
+ assert_eq ! ( Pin :: new( & mut future_a) . poll( & mut Context :: from_waker( & create_waker( ) . 1 ) ) , Poll :: Ready ( ( ) ) ) ;
757
+ assert_eq ! ( future_state. lock( ) . unwrap( ) . std_future_callbacks. len( ) , 0 ) ;
758
+ }
693
759
}
0 commit comments