about summary refs log tree commit diff
path: root/src/libstd/sys/unix/stack_overflow.rs
diff options
context:
space:
mode:
authorJack O'Connor <oconnor663@gmail.com>2019-08-01 12:04:28 -0400
committerJack O'Connor <oconnor663@gmail.com>2019-08-06 10:15:11 -0400
commitedb5214b29cd7de06dd10f673986d38e568b077c (patch)
tree4ab0f9081437c130d2bb82fb297e226512fb7b03 /src/libstd/sys/unix/stack_overflow.rs
parent8996328ebf34aa73e83a1db326767c11041f811d (diff)
downloadrust-edb5214b29cd7de06dd10f673986d38e568b077c.tar.gz
rust-edb5214b29cd7de06dd10f673986d38e568b077c.zip
avoid unnecessary reservations in std::io::Take::read_to_end
Prevously the `read_to_end` implementation for `std::io::Take` used its
own `limit` as a cap on the `reservation_size`. However, that could
still result in an over-allocation like this:

1. Call `reader.take(5).read_to_end(&mut vec)`.
2. `read_to_end_with_reservation` reserves 5 bytes and calls `read`.
3. `read` writes 5 bytes.
4. `read_to_end_with_reservation` reserves 5 bytes and calls `read`.
5. `read` writes 0 bytes.
6. The read loop ends with `vec` having length 5 and capacity 10.

The reservation of 5 bytes was correct for the read at step 2 but
unnecessary for the read at step 4. By that second read, `Take::limit`
is 0, but the `read_to_end_with_reservation` loop is still using the
same `reservation_size` it started with.

Solve this by having `read_to_end_with_reservation` take a closure,
which lets it get a fresh `reservation_size` for each read. This is an
implementation detail which doesn't affect any public API.
Diffstat (limited to 'src/libstd/sys/unix/stack_overflow.rs')
0 files changed, 0 insertions, 0 deletions