mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-08 00:00:13 +02:00
io: complete zero-length memory stream operations (#8323)
This commit is contained in:
@@ -250,6 +250,10 @@ impl SimplexStream {
|
|||||||
cx: &mut task::Context<'_>,
|
cx: &mut task::Context<'_>,
|
||||||
buf: &mut ReadBuf<'_>,
|
buf: &mut ReadBuf<'_>,
|
||||||
) -> Poll<std::io::Result<()>> {
|
) -> Poll<std::io::Result<()>> {
|
||||||
|
if buf.remaining() == 0 {
|
||||||
|
return Poll::Ready(Ok(()));
|
||||||
|
}
|
||||||
|
|
||||||
if self.buffer.has_remaining() {
|
if self.buffer.has_remaining() {
|
||||||
let max = self.buffer.remaining().min(buf.remaining());
|
let max = self.buffer.remaining().min(buf.remaining());
|
||||||
buf.put_slice(&self.buffer[..max]);
|
buf.put_slice(&self.buffer[..max]);
|
||||||
@@ -278,6 +282,10 @@ impl SimplexStream {
|
|||||||
if self.is_closed {
|
if self.is_closed {
|
||||||
return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
|
return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
|
||||||
}
|
}
|
||||||
|
if buf.is_empty() {
|
||||||
|
return Poll::Ready(Ok(0));
|
||||||
|
}
|
||||||
|
|
||||||
let avail = self.max_buf_size - self.buffer.len();
|
let avail = self.max_buf_size - self.buffer.len();
|
||||||
if avail == 0 {
|
if avail == 0 {
|
||||||
self.write_waker = Some(cx.waker().clone());
|
self.write_waker = Some(cx.waker().clone());
|
||||||
@@ -300,6 +308,10 @@ impl SimplexStream {
|
|||||||
if self.is_closed {
|
if self.is_closed {
|
||||||
return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
|
return Poll::Ready(Err(std::io::ErrorKind::BrokenPipe.into()));
|
||||||
}
|
}
|
||||||
|
if bufs.iter().all(|buf| buf.is_empty()) {
|
||||||
|
return Poll::Ready(Ok(0));
|
||||||
|
}
|
||||||
|
|
||||||
let avail = self.max_buf_size - self.buffer.len();
|
let avail = self.max_buf_size - self.buffer.len();
|
||||||
if avail == 0 {
|
if avail == 0 {
|
||||||
self.write_waker = Some(cx.waker().clone());
|
self.write_waker = Some(cx.waker().clone());
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![cfg(feature = "full")]
|
#![cfg(feature = "full")]
|
||||||
|
|
||||||
|
use futures::FutureExt;
|
||||||
|
use std::io::IoSlice;
|
||||||
use tokio::io::{duplex, AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{duplex, AsyncReadExt, AsyncWriteExt};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -101,6 +103,38 @@ async fn max_write_size() {
|
|||||||
drop(b);
|
drop(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn zero_length_operations() {
|
||||||
|
let (mut reader, _peer) = duplex(1);
|
||||||
|
assert!(matches!(reader.read(&mut []).now_or_never(), Some(Ok(0))));
|
||||||
|
|
||||||
|
let (mut writer, _peer) = duplex(1);
|
||||||
|
writer.write_all(b"x").await.unwrap();
|
||||||
|
assert!(matches!(writer.write(&[]).now_or_never(), Some(Ok(0))));
|
||||||
|
|
||||||
|
let (mut writer, _peer) = duplex(1);
|
||||||
|
writer.write_all(b"x").await.unwrap();
|
||||||
|
let bufs = [IoSlice::new(&[]), IoSlice::new(&[])];
|
||||||
|
assert!(matches!(
|
||||||
|
writer.write_vectored(&bufs).now_or_never(),
|
||||||
|
Some(Ok(0))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn zero_length_writes_to_closed_stream() {
|
||||||
|
let (mut writer, peer) = duplex(1);
|
||||||
|
drop(peer);
|
||||||
|
let err = writer.write(&[]).await.unwrap_err();
|
||||||
|
assert_eq!(err.kind(), std::io::ErrorKind::BrokenPipe);
|
||||||
|
|
||||||
|
let (mut writer, peer) = duplex(1);
|
||||||
|
drop(peer);
|
||||||
|
let bufs = [IoSlice::new(&[]), IoSlice::new(&[])];
|
||||||
|
let err = writer.write_vectored(&bufs).await.unwrap_err();
|
||||||
|
assert_eq!(err.kind(), std::io::ErrorKind::BrokenPipe);
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn duplex_is_cooperative() {
|
async fn duplex_is_cooperative() {
|
||||||
let (mut tx, mut rx) = tokio::io::duplex(1024 * 8);
|
let (mut tx, mut rx) = tokio::io::duplex(1024 * 8);
|
||||||
|
|||||||
Reference in New Issue
Block a user