From af9376300907dd187e0fdca793ccda2fa62de5ec Mon Sep 17 00:00:00 2001 From: Minh Vu Date: Mon, 10 Aug 2026 12:19:30 +0200 Subject: [PATCH] io: handle empty vectored writes in simplex (#8353) --- tokio-util/src/io/simplex.rs | 4 ++++ tokio-util/tests/io_simplex.rs | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/tokio-util/src/io/simplex.rs b/tokio-util/src/io/simplex.rs index 5aaf44e0d..39f4222de 100644 --- a/tokio-util/src/io/simplex.rs +++ b/tokio-util/src/io/simplex.rs @@ -291,6 +291,10 @@ impl AsyncWrite for Sender { return Poll::Ready(Err(IoError::new(IoErrorKind::BrokenPipe, CLOSED_ERROR_MSG))); } + if bufs.iter().all(|buf| buf.is_empty()) { + return Poll::Ready(Ok(0)); + } + let free = inner .backpressure_boundary .checked_sub(inner.buf.len()) diff --git a/tokio-util/tests/io_simplex.rs b/tokio-util/tests/io_simplex.rs index 0b54b7986..f541a7133 100644 --- a/tokio-util/tests/io_simplex.rs +++ b/tokio-util/tests/io_simplex.rs @@ -354,3 +354,16 @@ async fn poll_write_vectored_3() { let n = assert_ready!(tx.poll_write_vectored(&mut noop_context(), io_slices)).unwrap(); assert_eq!(n, 0); } + +/// The `Sender::poll_write_vectored` should return `Poll::Ready(Ok(0))` +/// if all the input buffers have zero length, even when the channel is full. +#[tokio::test] +async fn poll_write_vectored_4() { + let (mut tx, _rx) = simplex::new(1); + tx.write_all(&[1]).await.unwrap(); + + let io_slices = &[IoSlice::new(&[]), IoSlice::new(&[])]; + tokio::pin!(tx); + let n = assert_ready!(tx.poll_write_vectored(&mut noop_context(), io_slices)).unwrap(); + assert_eq!(n, 0); +}