Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add BytesMut::try_reserve() #613

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

poliorcetics
Copy link

@poliorcetics poliorcetics commented May 19, 2023

I rebased #521.

While I do not claim this implements #484, I think the review was too harsh: BytesMut is the only
API with a reserve method, adding other fallible allocations APIs should not be done in this MR.

@roblabla
Copy link

Hello, I also need this. Any way we can get this merged?

Copy link
Contributor

@Darksonn Darksonn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. This fell through the cracks. One nit below, otherwise I'm okay with adding this.

@@ -838,7 +906,10 @@ impl BytesMut {
return true;
}

self.reserve_inner(additional, false)
match self.reserve_inner(additional, false) {
Err(err) => panic!("fail to reserve: {}", err),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should call std::alloc::handle_alloc_error.

Copy link

@roblabla roblabla Oct 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This codepath (try_reclaim error case in reserve_inner) actually can't be reached (reserve_inner returns an error when it fails to allocate, but this codepath calls reserve_inner with allocate set to false). It should probably be changed to unreachable!().

For the other caller (try_reserve error case), it requires creating a Layout to pass to handle_alloc_error. This is not entirely straightforward. Ideally we'd extract the layout from TryReserveErrorKind but that's currently unstable, so we'll have to guess it.

I currently have this:

                let mut layout = Layout::new::<u8>();
                if let Ok(array_layout) = layout.array(self.len() + additional) {
                    layout = array_layout;
                }
                std::alloc::handle_alloc_error(array_layout);

Ergo we create a Layout of [u8; len + additional], and if that fails, we fallback to a simple layout of u8. I think that's good enough? In practice, [u8; len + additional] should always work out. But if len + additional overflows isize, it might error out - and I'm not sure what to give to handle_alloc_error in this case. Or maybe we should only call handle_alloc_error when we successfully create a Layout, and unwrap on the layout creation otherwise?

/// assert_eq!(buf.as_ptr(), ptr);
/// ```
#[inline]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also return our own error type. The one from std is not publicly constructable, which would mean our implementation would always need to call std, we couldn't refactor it.

@Darksonn
Copy link
Contributor

Actually, it seems like Vec::try_reserve is not available on our minimum supported rust version.

@roblabla
Copy link

Vec::try_reserve has been in Rust since 1.57, which was released in December 2, 2021 (almost three years ago). Is there any plan on raising the MSRV anytime soon? Otherwise would you accept a PR gating this API behind a feature gate?

@djc
Copy link

djc commented Oct 24, 2024

Given that even syn is at 1.61, I think a bump to 1.57 is fine.

paolobarbolini added a commit to paolobarbolini/img-parts that referenced this pull request Oct 26, 2024
1.56 would be enough for miniz_oxide 0.8 and edition 2021,
but bytes may bump it to 1.57 soon
tokio-rs/bytes#613 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants