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); +}