From d64c8e3ae0933faa5a951c5d351b347a8a1f2605 Mon Sep 17 00:00:00 2001 From: Josh Guilfoyle Date: Tue, 18 Jul 2023 18:28:30 -0700 Subject: [PATCH] poll: Do not clear readiness on short read/writes. (#5881) The new mio_unsupported_force_poll_poll behaviour works the same as Windows (using level-triggered APIs to mimic edge-triggered ones) and it depends on intercepting an EAGAIN result to start polling the fd again. --- tokio/src/io/poll_evented.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/tokio/src/io/poll_evented.rs b/tokio/src/io/poll_evented.rs index 875ad7e0d0a..f5e8cffb8f3 100644 --- a/tokio/src/io/poll_evented.rs +++ b/tokio/src/io/poll_evented.rs @@ -165,8 +165,10 @@ feature! { match self.io.as_ref().unwrap().read(b) { Ok(n) => { // if we read a partially full buffer, this is sufficient on unix to show - // that the socket buffer has been drained - if n > 0 && (!cfg!(windows) && n < len) { + // that the socket buffer has been drained. Unfortunately this assumption + // fails for level-triggered selectors (like on Windows or poll even for + // UNIX): https://github.com/tokio-rs/tokio/issues/5866 + if n > 0 && (!cfg!(windows) && !cfg!(mio_unsupported_force_poll_poll) && n < len) { self.registration.clear_readiness(evt); } @@ -196,8 +198,10 @@ feature! { match self.io.as_ref().unwrap().write(buf) { Ok(n) => { // if we write only part of our buffer, this is sufficient on unix to show - // that the socket buffer is full - if n > 0 && (!cfg!(windows) && n < buf.len()) { + // that the socket buffer is full. Unfortunately this assumption + // fails for level-triggered selectors (like on Windows or poll even for + // UNIX): https://github.com/tokio-rs/tokio/issues/5866 + if n > 0 && (!cfg!(windows) && !cfg!(mio_unsupported_force_poll_poll) && n < buf.len()) { self.registration.clear_readiness(evt); }