Skip to content

feat: add initialized_unfilled to ReadBufCursor#4115

Merged
seanmonstar merged 1 commit into
hyperium:masterfrom
abh1nav10:add-initialized-unfilled
Jul 7, 2026
Merged

feat: add initialized_unfilled to ReadBufCursor#4115
seanmonstar merged 1 commit into
hyperium:masterfrom
abh1nav10:add-initialized-unfilled

Conversation

@abh1nav10

@abh1nav10 abh1nav10 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

This PR adds initialize_unfilled and initialize_unfilled_to APIs to ReadBufCursor similar to the ones provided by tokio::io::ReadBuf. The caller still will have to maintain the responsibility to advance the cursor.

The requirement stems from the inability to zero initialize only the uninitialized part of ReadBuf. When implementing hyper::rt::Read for a type that implements futures::io::AsyncRead, in order to ensure that the buffer is fully initialized, we are left with no other option than to write

        let uninit = unsafe { buf.as_mut() };
        uninit.fill(MaybeUninit::new(0));

which has to pay the cost of re-initializing the part of the buffer that might have already been initialized previously and it becomes completely non-useful if the buffer was already completely initialized in the first place.

I analyzed a use case wherein the I found that the WebSocket type from tungstenite crate uses an internally managed BytesMut buffer which is zero initialized before reading from the type implementing io::Read that it is generic over.
The async_tungstenite crate provides such a type AllowStd<S> where S: futures::io::AsyncRead, and the io::Read impl for this type just calls into the poll_read of S.

When implementing a FuturesIo<T> type similar to hyper_util::rt::tokio::TokioIo, we implement futures::io::AsyncRead for it where T: hyper::rt::Read and call into the poll_read of T by calling ReadBuf::new on the buffer and passing buffer.unfilled() to it.
This circles back to our original impl of hyper::rt::Read for the HyperStream which does not have a way to zero initialize only the uninitialized portion of the buffer and hence has to zero out an already zeroed out buffer paying double the cost.

With the addition of this API, this problem can be avoided.

@seanmonstar

Copy link
Copy Markdown
Member

Cool, thanks! This makes sense to me. Clippy is noting that some safety comments are needed. 🤓

@abh1nav10 abh1nav10 force-pushed the add-initialized-unfilled branch from 4dde290 to 3ff5909 Compare July 7, 2026 03:16
@abh1nav10

Copy link
Copy Markdown
Contributor Author

Clippy should now be happy :)

@seanmonstar seanmonstar merged commit ccc1e85 into hyperium:master Jul 7, 2026
23 checks passed
@abh1nav10 abh1nav10 deleted the add-initialized-unfilled branch July 7, 2026 15:16
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.

2 participants