@@ -6,7 +6,7 @@ use std::os::unix::io::RawFd;
6
6
#[ cfg( windows) ]
7
7
use std:: os:: windows:: io:: RawSocket ;
8
8
use std:: panic;
9
- use std:: sync:: atomic:: { AtomicUsize , Ordering } ;
9
+ use std:: sync:: atomic:: { AtomicU8 , AtomicUsize , Ordering } ;
10
10
use std:: sync:: { Arc , Mutex , MutexGuard } ;
11
11
use std:: task:: { Poll , Waker } ;
12
12
use std:: thread;
@@ -166,6 +166,7 @@ impl Reactor {
166
166
readers : Vec :: new ( ) ,
167
167
writers : Vec :: new ( ) ,
168
168
} ) ,
169
+ wakers_registered : AtomicU8 :: new ( 0 ) ,
169
170
} ) ;
170
171
sources. insert ( source. clone ( ) ) ;
171
172
@@ -338,12 +339,18 @@ impl ReactorLock<'_> {
338
339
if ev. readable {
339
340
w. tick_readable = tick;
340
341
wakers. append ( & mut w. readers ) ;
342
+ source
343
+ . wakers_registered
344
+ . fetch_and ( !Source :: READERS_REGISTERED , Ordering :: SeqCst ) ;
341
345
}
342
346
343
347
// Wake writers if a writability event was emitted.
344
348
if ev. writable {
345
349
w. tick_writable = tick;
346
350
wakers. append ( & mut w. writers ) ;
351
+ source
352
+ . wakers_registered
353
+ . fetch_and ( !Source :: WRITERS_REGISTERED , Ordering :: SeqCst ) ;
347
354
}
348
355
349
356
// Re-register if there are still writers or
@@ -408,6 +415,9 @@ pub(crate) struct Source {
408
415
409
416
/// Tasks interested in events on this source.
410
417
wakers : Mutex < Wakers > ,
418
+
419
+ /// Whether there are wakers interrested in events on this source.
420
+ wakers_registered : AtomicU8 ,
411
421
}
412
422
413
423
/// Tasks interested in events on a source.
@@ -427,6 +437,9 @@ struct Wakers {
427
437
}
428
438
429
439
impl Source {
440
+ const READERS_REGISTERED : u8 = 1 << 0 ;
441
+ const WRITERS_REGISTERED : u8 = 1 << 1 ;
442
+
430
443
/// Waits until the I/O source is readable.
431
444
pub ( crate ) async fn readable ( & self ) -> io:: Result < ( ) > {
432
445
let mut ticks = None ;
@@ -453,6 +466,8 @@ impl Source {
453
466
writable : !w. writers . is_empty ( ) ,
454
467
} ,
455
468
) ?;
469
+ self . wakers_registered
470
+ . fetch_or ( Self :: READERS_REGISTERED , Ordering :: SeqCst ) ;
456
471
}
457
472
458
473
// Register the current task's waker if not present already.
@@ -473,6 +488,11 @@ impl Source {
473
488
. await
474
489
}
475
490
491
+ pub ( crate ) fn readers_registered ( & self ) -> bool {
492
+ self . wakers_registered . load ( Ordering :: SeqCst ) & Self :: READERS_REGISTERED
493
+ == Self :: READERS_REGISTERED
494
+ }
495
+
476
496
/// Waits until the I/O source is writable.
477
497
pub ( crate ) async fn writable ( & self ) -> io:: Result < ( ) > {
478
498
let mut ticks = None ;
@@ -499,6 +519,8 @@ impl Source {
499
519
writable : true ,
500
520
} ,
501
521
) ?;
522
+ self . wakers_registered
523
+ . fetch_or ( Self :: WRITERS_REGISTERED , Ordering :: SeqCst ) ;
502
524
}
503
525
504
526
// Register the current task's waker if not present already.
@@ -518,4 +540,9 @@ impl Source {
518
540
} )
519
541
. await
520
542
}
543
+
544
+ pub ( crate ) fn writers_registered ( & self ) -> bool {
545
+ self . wakers_registered . load ( Ordering :: SeqCst ) & Self :: WRITERS_REGISTERED
546
+ == Self :: WRITERS_REGISTERED
547
+ }
521
548
}
0 commit comments