diff --git a/tokio/src/io/blocking.rs b/tokio/src/io/blocking.rs index f189136b52e..6c43dc14e42 100644 --- a/tokio/src/io/blocking.rs +++ b/tokio/src/io/blocking.rs @@ -21,6 +21,7 @@ pub(crate) struct Blocking { pub(crate) struct Buf { buf: Vec, pos: usize, + init_len: usize, } pub(crate) const DEFAULT_MAX_BUF_SIZE: usize = 2 * 1024 * 1024; @@ -190,6 +191,7 @@ impl Buf { Buf { buf: Vec::with_capacity(n), pos: 0, + init_len: 0, } } @@ -220,6 +222,7 @@ impl Buf { let n = cmp::min(src.len(), max_buf_size); self.buf.extend_from_slice(&src[..n]); + self.init_len = cmp::max(self.init_len, self.buf.len()); n } @@ -236,6 +239,18 @@ impl Buf { self.buf.reserve(len - self.buf.len()); } + if self.init_len < len { + debug_assert!(self.init_len < self.buf.capacity(), "init_len of Vec is bigger than the capacity"); + debug_assert!(len <= self.buf.capacity(), "uninit area of Vec is bigger than the capacity"); + + let uninit_len = len - self.init_len; + // SAFETY: the area is within the allocation of the Vec + unsafe { + self.buf.as_mut_ptr().add(self.init_len).write_bytes(0, uninit_len); + } + } + + // SAFETY: `len` is within the capacity and is init unsafe { self.buf.set_len(len); } @@ -287,6 +302,7 @@ cfg_fs! { self.buf.extend_from_slice(&buf[..len]); rem -= len; } + self.init_len = cmp::max(self.init_len, self.buf.len()); max_buf_size - rem }