Skip to content

Commit defb205

Browse files
authored
reactor: properly reset registered wakers state when needed (async-rs#13)
If the list of pending wakers grew too big and we woke everything, also drop the bit from wakers_registered Signed-off-by: Marc-Antoine Perennou <[email protected]>
1 parent e91d306 commit defb205

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

src/reactor.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,10 @@ impl Source {
473473
// Register the current task's waker if not present already.
474474
if w.readers.iter().all(|w| !w.will_wake(cx.waker())) {
475475
w.readers.push(cx.waker().clone());
476-
limit_waker_list(&mut w.readers);
476+
if limit_waker_list(&mut w.readers) {
477+
self.wakers_registered
478+
.fetch_and(!Self::READERS_REGISTERED, Ordering::SeqCst);
479+
}
477480
}
478481

479482
// Remember the current ticks.
@@ -527,7 +530,10 @@ impl Source {
527530
// Register the current task's waker if not present already.
528531
if w.writers.iter().all(|w| !w.will_wake(cx.waker())) {
529532
w.writers.push(cx.waker().clone());
530-
limit_waker_list(&mut w.writers);
533+
if limit_waker_list(&mut w.writers) {
534+
self.wakers_registered
535+
.fetch_and(!Self::WRITERS_REGISTERED, Ordering::SeqCst);
536+
}
531537
}
532538

533539
// Remember the current ticks.
@@ -549,7 +555,7 @@ impl Source {
549555
}
550556
}
551557

552-
/// Wakes up all wakers in the list if it grew too big.
558+
/// Wakes up all wakers in the list if it grew too big and returns whether it did.
553559
///
554560
/// The waker list keeps growing in pathological cases where a single async I/O handle has lots of
555561
/// different reader or writer tasks. If the number of interested wakers crosses some threshold, we
@@ -562,11 +568,14 @@ impl Source {
562568
/// However, we don't worry about such scenarios because it's very unlikely to have more than two
563569
/// actually concurrent tasks operating on a single async I/O handle. If we happen to cross the
564570
/// aforementioned threshold, we have bigger problems to worry about.
565-
fn limit_waker_list(wakers: &mut Vec<Waker>) {
571+
fn limit_waker_list(wakers: &mut Vec<Waker>) -> bool {
566572
if wakers.len() > 50 {
567573
for waker in wakers.drain(..) {
568574
// Don't let a panicking waker blow everything up.
569575
let _ = panic::catch_unwind(|| waker.wake());
570576
}
577+
true
578+
} else {
579+
false
571580
}
572581
}

0 commit comments

Comments
 (0)