Skip to content

Conversation

@toksdotdev
Copy link
Contributor

This MR addresses an issue where a panic occurs while attempting to read messages larger than the buffer size for Windows named pipes (this is hardcoded to 4096 bytes).

panicked at C:\Users\toks\mio\src\sys\windows\named_pipe.rs:900:17:
assertion `left == right` failed
  left: 4096
 right: 0

Root Cause

Per MS docs:

If a named pipe is being read in message mode and the next message is longer than the nNumberOfBytesToRead parameter specifies, ReadFile returns FALSE and GetLastError returns ERROR_MORE_DATA. The remainder of the message can be read by a subsequent call to the ReadFile or PeekNamedPipe function.

Furthermore, if the provided buffer to the overlapped read operation has free capacity, data would be copied into it. However, since no special handling is given to ERROR_MORE_DATA, the bytes transfered == 0 assertion would be executed, causing the above panic (where 4096 is the number of bytes read despite an ERROR_MORE_DATA error).

Solution

The core idea is to gracefully handle ERROR_MORE_DATA, and subsequently transition the named pipe's internal state back to a State::Ok(buf, 0), where buf is any unread data; then repeat this until the last set of bytes of the message is copied, and ERROR_MORE_DATA is no longer returned.

For added context (given this part of the code is poorly documented): the repeat until no ERROR_MORE_DATA is achieved when an overlapped read is scheduled via schedule_read(..), and on an I/O completion port event, read_done(...) being called to transition to an "end" state in preparation for the next Read::read(..) call.

I've also added relevant tests to verify the new behaviour.

Related Issues

Other Observations

I noticed tokio-rs/tokio#5307 is also used to track this issue. However, I believe they're two distinct problems. This handles the case where more data needs to be read, but can't because we panic mid-way, while the other is more concerned about tweaking the buffer size of the named pipe (which imo is up to the implementer).

BTW, one could achieve similar fix by leveraging a larger buffer (tokio-rs/tokio#5307) since there'd be enough capacity for the entire message to fit in. But that has its own tradeoffs primarily due to the large buffer size.

Copy link
Collaborator

@Thomasdezeeuw Thomasdezeeuw left a comment

Choose a reason for hiding this comment

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

I'm no Windows expert, but the code and tests LGTM me. I'm going to ask if someone with some more Windows knowledge can review this, if not I'm going to merge this.

@toksdotdev
Copy link
Contributor Author

thanks for taking a look. i've addressed the feedbacks.

@toksdotdev
Copy link
Contributor Author

checking in on this. any luck getting someone else with with windows experience to review?

@Thomasdezeeuw
Copy link
Collaborator

I forgot to merge this after starting the CI, merging now.

@Thomasdezeeuw Thomasdezeeuw merged commit 02f69ea into tokio-rs:master Dec 3, 2025
59 checks passed
@Thomasdezeeuw
Copy link
Collaborator

Thanks @toksdotdev

@toksdotdev toksdotdev deleted the toks/handle-error-more-data branch December 3, 2025 16:24
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