@@ -26,7 +26,7 @@ use std::marker::PhantomData;
26
26
use std:: panic:: { RefUnwindSafe , UnwindSafe } ;
27
27
use std:: pin:: Pin ;
28
28
use std:: rc:: Rc ;
29
- use std:: sync:: atomic:: { AtomicBool , Ordering , AtomicU64 , AtomicUsize } ;
29
+ use std:: sync:: atomic:: { AtomicBool , AtomicUsize , Ordering } ;
30
30
use std:: sync:: { Arc , Mutex , RwLock } ;
31
31
use std:: task:: { Context , Poll , Waker } ;
32
32
@@ -199,7 +199,7 @@ impl State {
199
199
sleepers : Mutex :: new ( Sleepers {
200
200
count : 0 ,
201
201
wakers : Vec :: new ( ) ,
202
- id_gen : 1 ,
202
+ free_ids : Vec :: new ( ) ,
203
203
} ) ,
204
204
}
205
205
}
@@ -228,17 +228,19 @@ struct Sleepers {
228
228
/// IDs and wakers of sleeping unnotified tickers.
229
229
///
230
230
/// A sleeping ticker is notified when its waker is missing from this list.
231
- wakers : Vec < ( u64 , Waker ) > ,
231
+ wakers : Vec < ( usize , Waker ) > ,
232
232
233
- /// ID generator for sleepers .
234
- id_gen : u64 ,
233
+ /// Reclaimed IDs .
234
+ free_ids : Vec < usize > ,
235
235
}
236
236
237
237
impl Sleepers {
238
238
/// Inserts a new sleeping ticker.
239
- fn insert ( & mut self , waker : & Waker ) -> u64 {
240
- let id = self . id_gen ;
241
- self . id_gen += 1 ;
239
+ fn insert ( & mut self , waker : & Waker ) -> usize {
240
+ let id = match self . free_ids . pop ( ) {
241
+ Some ( id) => id,
242
+ None => self . count + 1 ,
243
+ } ;
242
244
self . count += 1 ;
243
245
self . wakers . push ( ( id, waker. clone ( ) ) ) ;
244
246
id
@@ -247,7 +249,7 @@ impl Sleepers {
247
249
/// Re-inserts a sleeping ticker's waker if it was notified.
248
250
///
249
251
/// Returns `true` if the ticker was notified.
250
- fn update ( & mut self , id : u64 , waker : & Waker ) -> bool {
252
+ fn update ( & mut self , id : usize , waker : & Waker ) -> bool {
251
253
for item in & mut self . wakers {
252
254
if item. 0 == id {
253
255
if !item. 1 . will_wake ( waker) {
@@ -264,8 +266,10 @@ impl Sleepers {
264
266
/// Removes a previously inserted sleeping ticker.
265
267
///
266
268
/// Returns `true` if the ticker was notified.
267
- fn remove ( & mut self , id : u64 ) -> bool {
269
+ fn remove ( & mut self , id : usize ) -> bool {
268
270
self . count -= 1 ;
271
+ self . free_ids . push ( id) ;
272
+
269
273
for i in ( 0 ..self . wakers . len ( ) ) . rev ( ) {
270
274
if self . wakers [ i] . 0 == id {
271
275
self . wakers . remove ( i) ;
@@ -494,15 +498,15 @@ struct Ticker<'a> {
494
498
/// 1) Woken.
495
499
/// 2a) Sleeping and unnotified.
496
500
/// 2b) Sleeping and notified.
497
- sleeping : AtomicU64 ,
501
+ sleeping : AtomicUsize ,
498
502
}
499
503
500
504
impl Ticker < ' _ > {
501
505
/// Creates a ticker.
502
506
fn new ( state : & State ) -> Ticker < ' _ > {
503
507
Ticker {
504
508
state,
505
- sleeping : AtomicU64 :: new ( 0 ) ,
509
+ sleeping : AtomicUsize :: new ( 0 ) ,
506
510
}
507
511
}
508
512
@@ -514,7 +518,9 @@ impl Ticker<'_> {
514
518
515
519
match self . sleeping . load ( Ordering :: SeqCst ) {
516
520
// Move to sleeping state.
517
- 0 => self . sleeping . store ( sleepers. insert ( waker) , Ordering :: SeqCst ) ,
521
+ 0 => self
522
+ . sleeping
523
+ . store ( sleepers. insert ( waker) , Ordering :: SeqCst ) ,
518
524
519
525
// Already sleeping, check if notified.
520
526
id => {
0 commit comments