From 8c1863065cd5dd64c4832ce9c5824caba8e7cccb Mon Sep 17 00:00:00 2001 From: Oliver Bunting <72926894+ollie-etl@users.noreply.github.com> Date: Thu, 14 Sep 2023 11:17:23 +0100 Subject: [PATCH] Fix race condition in next_when_notified --- src/buf/fixed/pool.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/buf/fixed/pool.rs b/src/buf/fixed/pool.rs index 409d27e9..5bea4afb 100644 --- a/src/buf/fixed/pool.rs +++ b/src/buf/fixed/pool.rs @@ -274,8 +274,10 @@ impl FixedBufPool { pin!(notified); loop { // In the single-threaded case, no buffers could get checked in - // between us calling `try_next` and here, so we can't miss a wakeup. - notified.as_mut().await; + // between us calling `try_next` and here. However, we may still miss a wake-up, + // as multiple check-ins can occur before any waking tasks are scheduled, + // which would result in the loss of a permit + notified.as_mut().enable(); if let Some(data) = self.inner.borrow_mut().try_next(cap) { // Safety: the validity of buffer data is ensured by @@ -284,6 +286,9 @@ impl FixedBufPool { return buf; } + // Await notify_one + notified.as_mut().await; + // It's possible that the task did not get a buffer from `try_next`. // The `Notify` entries are created once for each requested capacity // and never removed, so this `Notify` could have been holding