fix: wake MCP session::recv when SSE stream closes - #69
Merged
Conversation
ruoka
force-pushed
the
cursor/critical-bug-management-c962
branch
from
August 2, 2026 01:36
b4034e0 to
970209c
Compare
ruoka
marked this pull request as ready for review
August 2, 2026 01:36
Unbounded recv() used cv.wait, which is only notified by POST enqueue or erase_session. Stream failure (client disconnect after write / failbit) never re-checked m_stream.closed(), so attach handlers blocked forever and http::server stop/join could hang. Slice the wait and add a unit regression that sets badbit while recv is blocked. Co-authored-by: Kaius Ruokonen <ruoka@users.noreply.github.com>
Avoid ambiguous lookup against net::detail from structured_log_stream. Co-authored-by: Kaius Ruokonen <ruoka@users.noreply.github.com>
ruoka
force-pushed
the
cursor/critical-bug-management-c962
branch
from
August 2, 2026 01:37
970209c to
d0e7e6c
Compare
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.
Bug and impact
http::mcp::session::recv()with the default unbounded timeout usedcv.wait. That wait is only notified by POST enqueue orerase_session. When the SSE stream becomes not good (client disconnect after a write sets failbit, or any path that makessse::session::closed()true),ready()'sm_stream.closed()clause was never re-checked.Custom
sse_transport::attachhandlers that block inrecv()can hang forever after the stream dies, leaving the SSE handler thread alive sohttp::server::stop()→wait_for_handlers()never completes.mcp::server::run_sessionalready avoids this with a 1s timedrecv+send_commentprobe; the publicsession::recv()default did not.Root cause
cv.waitonly re-evaluates its predicate on notify. Stream close/failbit never notifies the session CV.Fix
Slice the unbounded wait with
wait_for(50ms) som_stream.closed()is re-checked. Timedrecv(timeout > 0)was already correct.Complementary to open PR #68 (shutdown latch for poll-only
closed()): #68 makesstop()visible without a write; this PR makesrecv()notice onceclosed()is true.Validation
recv()returnsnulloptwithin 2s afterbadbitis set on the underlying stream (no CV notify).test_case.*MCP— 25/25 passed (89 assertions).Note
Medium Risk
Changes blocking/wakeup semantics on the MCP SSE session path; incorrect behavior could still strand handler threads during shutdown, but the change is narrow and covered by a regression test.
Overview
Fixes a hang when
session::recv()is called with the default unbounded timeout while the SSE stream dies without a condition-variable notify (client disconnect /failbit).recv()no longer uses a singlecv.waitfor that path. It loops onwait_for(50ms)soready()periodically re-evaluatesm_stream.closed(), matching the behavior callers already get with a positive timeout. Timedrecvis unchanged.Adds a regression test: unbounded
recv()on astringstream-backed SSE session returnsnulloptwithin 2s afterbadbitis set, with no POST or session erase.Reviewed by Cursor Bugbot for commit d0e7e6c. Bugbot is set up for automated code reviews on this repo. Configure here.