Repository navigation
fix: curl_exec() in a coroutine resumes after curl_pause(CONT) - #3
Merged
Merged
Conversation
…l_pause(CONT) A paused transfer (a WRITEFUNCTION returning CURL_WRITEFUNC_PAUSE) keeps its socket ready, so curl_multi_select() reports activity at once while curl_multi_exec() moves nothing. curl_exec()'s cooperative loop then spun without ever yielding, and the coroutine that would call curl_pause(CONT) never ran. When the select reported activity but no bytes moved since the last round, the loop now sleeps through the scheduler (1ms, doubling to 20ms) before trying again. Found by fiber-interop/guzzle (PR #1), which pauses streaming bodies above 1 MiB buffered. curl_exec_pause_resume.phpt streams 4 MiB through a WRITEFUNCTION that pauses above 256 KiB, drained and resumed by a second coroutine; it hung on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B3u6DU5NmXoDe7i56CMT49
…nd TLS handshake rounds The stall check counted body bytes only, so the ready rounds of a connect, a TLS handshake and the header receipt looked stuck and added sleeps to every HTTPS request (p50 +2ms on localhost). Header bytes now count as progress, and only four ready rounds in a row without progress back off. The preempt test waits up to 200ms for a joined thread's /proc entry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B3u6DU5NmXoDe7i56CMT49
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.
A transfer paused by its WRITEFUNCTION (
CURL_WRITEFUNC_PAUSE) keeps its socket ready, socurl_multi_select()reports activity immediately whilecurl_multi_exec()makes no progress. The cooperativecurl_exec()loop in io.c therefore spun at 100% CPU without yielding, and the coroutine that would callcurl_pause($h, CURLPAUSE_CONT)never got to run: curl_exec() hung forever.Fix: when the select reported activity but the handle's byte count (
CURLINFO_SIZE_DOWNLOAD_T+CURLINFO_SIZE_UPLOAD_T) has not changed since the last round, sleep through the scheduler (1ms, doubling to 20ms) before trying again.Regression test:
tests/curl_exec_pause_resume.phptstreams 4 MiB through a WRITEFUNCTION that pauses above 256 KiB. A second coroutine drains the buffer and resumes the transfer. The child process is killed after 15s, so a hang shows up as a failure. On main the test hangs. With the fix, the full suite passes (169 passed, 16 skipped).Found by fiber-interop/guzzle PR #1, which pauses streaming bodies above 1 MiB buffered.
🤖 Generated with Claude Code
https://claude.ai/code/session_01B3u6DU5NmXoDe7i56CMT49