Fix 100% CPU utilization when write closed#72
Merged
Conversation
The workspace conversion moved the crate into ktls/ but left tests/ at the workspace root. The root is a virtual manifest, which owns no test targets, so cargo has not discovered or run the integration suite since: 'cargo test --workspace' builds only the two unit-test binaries. Move the directory into the ktls package, whose dev-dependencies it already uses.
Once write_closed is set — the peer sent close_notify or a fatal alert, or we shut the stream down — poll_write returned Ready(Ok(0)) forever. Ok(0) is a poor fit here: callers that retry short writes cannot make progress and spin at 100% CPU. We hit exactly that in production through h2, whose frame-write loop re-polls until its buffer drains. Return BrokenPipe instead, matching what writing to the raw socket after shutdown would produce (EPIPE). The existing write-after-shutdown assertions passed only because write_all's zero-write fallback produced the error; assert on a bare write and the error kind so the stream's own behavior is pinned, and cover the peer-initiated close path on both the client and server sides.
djc
approved these changes
Jul 16, 2026
djc
left a comment
Member
There was a problem hiding this comment.
I guess this makes sense?
ktls hasn't had much maintenance recently but this looks simple enough that it might make sense to merge and release.
Contributor
Author
Yes, I think it's an important bug to address, so a good idea to merge/release. I setup a reproducer, and verified that this PR fixes the issue. |
ctz
approved these changes
Jul 16, 2026
djc
approved these changes
Jul 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes a bug we saw in production. There's a nasty interaction between
h2and thektlscrate. Namely:ktlscrate returnsOk(0)instead of an error.h2retriesOk(0)writes, instead of treating them as errors.This led to busy looping, and 100% CPU utilization. I'm fixing this in both the
h2andktlscrates. Theh2variant of the fix is here: hyperium/h2#921.