From 04710e27d260b82865b3d4949e2e84b59c35ed66 Mon Sep 17 00:00:00 2001 From: BenoƮt du Garreau Date: Wed, 22 May 2024 11:41:19 +0200 Subject: Fix `io::BufReader` uses of `read_buf` --- library/std/src/io/buffered/bufreader/buffer.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'library/std/src/io/buffered/bufreader/buffer.rs') diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 1bf84d8bef3..68b024bb98a 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -133,11 +133,13 @@ impl Buffer { buf.set_init(self.initialized); } - reader.read_buf(buf.unfilled())?; + let result = reader.read_buf(buf.unfilled()); self.pos = 0; self.filled = buf.len(); self.initialized = buf.init_len(); + + result?; } Ok(self.buffer()) } -- cgit 1.4.1-3-g733a5 From 1e9a50dde8fe417348a9e4c74787975527502ec3 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Tue, 24 Sep 2024 13:33:31 -0700 Subject: Pre-allocate buffers in `File::open_buffered` and `create_buffered` --- library/std/src/fs.rs | 10 ++++++++-- library/std/src/io/buffered/bufreader.rs | 8 ++++++++ library/std/src/io/buffered/bufreader/buffer.rs | 12 +++++++++++- library/std/src/io/buffered/bufwriter.rs | 10 ++++++++++ library/std/src/lib.rs | 1 + 5 files changed, 38 insertions(+), 3 deletions(-) (limited to 'library/std/src/io/buffered/bufreader/buffer.rs') diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 6d1005272c6..b8e3f316beb 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -407,7 +407,10 @@ impl File { /// ``` #[unstable(feature = "file_buffered", issue = "none")] pub fn open_buffered>(path: P) -> io::Result> { - File::open(path).map(io::BufReader::new) + // Allocate the buffer *first* so we don't affect the filesystem otherwise. + let buffer = io::BufReader::::try_new_buffer()?; + let file = File::open(path)?; + Ok(io::BufReader::with_buffer(file, buffer)) } /// Opens a file in write-only mode. @@ -472,7 +475,10 @@ impl File { /// ``` #[unstable(feature = "file_buffered", issue = "none")] pub fn create_buffered>(path: P) -> io::Result> { - File::create(path).map(io::BufWriter::new) + // Allocate the buffer *first* so we don't affect the filesystem otherwise. + let buffer = io::BufWriter::::try_new_buffer()?; + let file = File::create(path)?; + Ok(io::BufWriter::with_buffer(file, buffer)) } /// Creates a new file in read-write mode; error if the file exists. diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs index e51dde994de..fcb3e36027b 100644 --- a/library/std/src/io/buffered/bufreader.rs +++ b/library/std/src/io/buffered/bufreader.rs @@ -74,6 +74,14 @@ impl BufReader { BufReader::with_capacity(DEFAULT_BUF_SIZE, inner) } + pub(crate) fn try_new_buffer() -> io::Result { + Buffer::try_with_capacity(DEFAULT_BUF_SIZE) + } + + pub(crate) fn with_buffer(inner: R, buf: Buffer) -> Self { + Self { inner, buf } + } + /// Creates a new `BufReader` with the specified buffer capacity. /// /// # Examples diff --git a/library/std/src/io/buffered/bufreader/buffer.rs b/library/std/src/io/buffered/bufreader/buffer.rs index 1bf84d8bef3..3df7e3971da 100644 --- a/library/std/src/io/buffered/bufreader/buffer.rs +++ b/library/std/src/io/buffered/bufreader/buffer.rs @@ -10,7 +10,7 @@ //! without encountering any runtime bounds checks. use crate::cmp; -use crate::io::{self, BorrowedBuf, Read}; +use crate::io::{self, BorrowedBuf, ErrorKind, Read}; use crate::mem::MaybeUninit; pub struct Buffer { @@ -36,6 +36,16 @@ impl Buffer { Self { buf, pos: 0, filled: 0, initialized: 0 } } + #[inline] + pub fn try_with_capacity(capacity: usize) -> io::Result { + match Box::try_new_uninit_slice(capacity) { + Ok(buf) => Ok(Self { buf, pos: 0, filled: 0, initialized: 0 }), + Err(_) => { + Err(io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate read buffer")) + } + } + } + #[inline] pub fn buffer(&self) -> &[u8] { // SAFETY: self.pos and self.cap are valid, and self.cap => self.pos, and diff --git a/library/std/src/io/buffered/bufwriter.rs b/library/std/src/io/buffered/bufwriter.rs index 13516d3b961..c41bae2aa4e 100644 --- a/library/std/src/io/buffered/bufwriter.rs +++ b/library/std/src/io/buffered/bufwriter.rs @@ -94,6 +94,16 @@ impl BufWriter { BufWriter::with_capacity(DEFAULT_BUF_SIZE, inner) } + pub(crate) fn try_new_buffer() -> io::Result> { + Vec::try_with_capacity(DEFAULT_BUF_SIZE).map_err(|_| { + io::const_io_error!(ErrorKind::OutOfMemory, "failed to allocate write buffer") + }) + } + + pub(crate) fn with_buffer(inner: W, buf: Vec) -> Self { + Self { inner, buf, panicked: false } + } + /// Creates a new `BufWriter` with at least the specified buffer capacity. /// /// # Examples diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 4d93af6ea65..b81e7c18abb 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -374,6 +374,7 @@ #![feature(slice_concat_trait)] #![feature(thin_box)] #![feature(try_reserve_kind)] +#![feature(try_with_capacity)] #![feature(vec_into_raw_parts)] // tidy-alphabetical-end // -- cgit 1.4.1-3-g733a5