Skip to content

Commit

Permalink
Fix unnecessary zeroing for AsyncRead implementors
Browse files Browse the repository at this point in the history
  • Loading branch information
MikailBag committed May 12, 2020
1 parent 1cc0168 commit 6a21dec
Show file tree
Hide file tree
Showing 10 changed files with 67 additions and 0 deletions.
6 changes: 6 additions & 0 deletions tokio/src/fs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,12 @@ impl File {
}

impl AsyncRead for File {
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
// std::fs::File does not need zeroing
// https://github.com/rust-lang/rust/blob/09c817eeb29e764cfc12d0a8d94841e3ffe34023/src/libstd/fs.rs#L668
false
}

fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand Down
22 changes: 22 additions & 0 deletions tokio/src/io/async_read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,28 @@ use std::ops::DerefMut;
use std::pin::Pin;
use std::task::{Context, Poll};

/// This utility function shoyld be used to override `AsyncRead::prepare_uninitialized_buffer`
/// for any AsyncRead impl which wraps an `std::io::Read` instance.
pub(crate) fn prepare_uninitialized_buffer_std_read<R: std::io::Read>(
buf: &mut [MaybeUninit<u8>],
) -> bool {
// TODO: when std::io::Initializer is stable, it should be used
// to override `prepare_uninitialized_buffer`
/*use std::io::Read;
if !T::initializer::should_initialize() {
return false;
}
*/
for x in buf {
// we could use safe method x.write(0) here, but it is unstable.
// Safety: as_mut_ptr() returns valid writeable pointer.
unsafe {
x.as_mut_ptr().write(0);
}
}
true
}

/// Reads bytes from a source.
///
/// This trait is analogous to the [`std::io::Read`] trait, but integrates with
Expand Down
4 changes: 4 additions & 0 deletions tokio/src/io/blocking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ impl<T> AsyncRead for Blocking<T>
where
T: Read + Unpin + Send + 'static,
{
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
crate::io::prepare_uninitialized_buffer_std_read::<T>(buf)
}

fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand Down
1 change: 1 addition & 0 deletions tokio/src/io/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ pub use self::async_buf_read::AsyncBufRead;

mod async_read;
pub use self::async_read::AsyncRead;
pub(crate) use self::async_read::prepare_uninitialized_buffer_std_read;

mod async_seek;
pub use self::async_seek::AsyncSeek;
Expand Down
4 changes: 4 additions & 0 deletions tokio/src/io/poll_evented.rs
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ impl<E> AsyncRead for PollEvented<E>
where
E: Evented + Read + Unpin,
{
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
crate::io::prepare_uninitialized_buffer_std_read::<E>(buf)
}

fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand Down
5 changes: 5 additions & 0 deletions tokio/src/io/stdin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ impl std::os::windows::io::AsRawHandle for Stdin {
}

impl AsyncRead for Stdin {
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
// https://github.com/rust-lang/rust/blob/09c817eeb29e764cfc12d0a8d94841e3ffe34023/src/libstd/io/stdio.rs#L97
false
}

fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand Down
9 changes: 9 additions & 0 deletions tokio/src/io/util/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ where
T: AsyncRead,
U: AsyncRead,
{
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
if self.first.prepare_uninitialized_buffer(buf) {
return true;
}
if self.second.prepare_uninitialized_buffer(buf) {
return true;
}
false
}
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand Down
3 changes: 3 additions & 0 deletions tokio/src/io/util/empty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ cfg_io_util! {
}

impl AsyncRead for Empty {
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
false
}
#[inline]
fn poll_read(
self: Pin<&mut Self>,
Expand Down
3 changes: 3 additions & 0 deletions tokio/src/io/util/repeat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ cfg_io_util! {
}

impl AsyncRead for Repeat {
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
false
}
#[inline]
fn poll_read(
self: Pin<&mut Self>,
Expand Down
10 changes: 10 additions & 0 deletions tokio/src/process/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,11 @@ impl AsyncWrite for ChildStdin {
}

impl AsyncRead for ChildStdout {
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
// https://github.com/rust-lang/rust/blob/09c817eeb29e764cfc12d0a8d94841e3ffe34023/src/libstd/process.rs#L314
false
}

fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand All @@ -882,6 +887,11 @@ impl AsyncRead for ChildStdout {
}

impl AsyncRead for ChildStderr {
unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [std::mem::MaybeUninit<u8>]) -> bool {
// https://github.com/rust-lang/rust/blob/09c817eeb29e764cfc12d0a8d94841e3ffe34023/src/libstd/process.rs#L375
false
}

fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
Expand Down

0 comments on commit 6a21dec

Please sign in to comment.