diff --git a/tokio/src/io/blocking.rs b/tokio/src/io/blocking.rs index f189136b52e..ebc32c5c6ef 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,27 @@ 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 +311,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 }