Skip to content

Commit 4b3da20

Browse files
authored
fs: empty reads on File should not start a background read (#7139)
1 parent b8ac94e commit 4b3da20

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

tokio/src/fs/file.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ impl AsyncRead for File {
587587
dst: &mut ReadBuf<'_>,
588588
) -> Poll<io::Result<()>> {
589589
ready!(crate::trace::trace_leaf(cx));
590+
590591
let me = self.get_mut();
591592
let inner = me.inner.get_mut();
592593

@@ -595,7 +596,7 @@ impl AsyncRead for File {
595596
State::Idle(ref mut buf_cell) => {
596597
let mut buf = buf_cell.take().unwrap();
597598

598-
if !buf.is_empty() {
599+
if !buf.is_empty() || dst.remaining() == 0 {
599600
buf.copy_to(dst);
600601
*buf_cell = Some(buf);
601602
return Poll::Ready(Ok(()));

tokio/tests/fs_file.rs

+19
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![warn(rust_2018_idioms)]
22
#![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations
33

4+
use futures::future::FutureExt;
45
use std::io::prelude::*;
56
use std::io::IoSlice;
67
use tempfile::NamedTempFile;
@@ -176,6 +177,24 @@ async fn read_file_from_std() {
176177
assert_eq!(&buf[..n], HELLO);
177178
}
178179

180+
#[tokio::test]
181+
async fn empty_read() {
182+
let mut tempfile = tempfile();
183+
tempfile.write_all(HELLO).unwrap();
184+
185+
let mut file = File::open(tempfile.path()).await.unwrap();
186+
187+
// Perform an empty read and get a length of zero.
188+
assert!(matches!(file.read(&mut []).now_or_never(), Some(Ok(0))));
189+
190+
// Check that we don't get EOF on the next read.
191+
let mut buf = [0; 1024];
192+
let n = file.read(&mut buf).await.unwrap();
193+
194+
assert_eq!(n, HELLO.len());
195+
assert_eq!(&buf[..n], HELLO);
196+
}
197+
179198
fn tempfile() -> NamedTempFile {
180199
NamedTempFile::new().unwrap()
181200
}

0 commit comments

Comments
 (0)