Skip to content

dict: avoid busy-loop in sendf() when the socket is not writable - #22576

Closed
thomas-chauchefoin-tob wants to merge 1 commit into
curl:masterfrom
thomas-chauchefoin-tob:fix-dict-sendf-loop
Closed

thomas-chauchefoin-tob wants to merge 1 commit into
curl:masterfrom
thomas-chauchefoin-tob:fix-dict-sendf-loop

Conversation

@thomas-chauchefoin-tob

Copy link
Copy Markdown
Contributor

Curl_xfer_send() reports CURLE_AGAIN as a successful zero-byte send, so the retry loop spun at 100% CPU and ignored the timeout when the peer stopped draining. Wait for writability and check the remaining time between retries, like gopher_do() already does.

Found while investigating the timeout in coverage collection for the curl_fuzzer_dict fuzzer on OSS-Fuzz.

Curl_xfer_send() reports CURLE_AGAIN as a successful zero-byte send, so
the retry loop spun at 100% CPU and ignored the timeout when the peer
stopped draining. Wait for writability and check the remaining time
between retries.
@github-actions github-actions Bot added the DICT label Aug 13, 2026
@icing

icing commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

An ancient corner of curl's protocols, basically from 1999.

The "real" solution would be to format a send buffer and never return done == TRUE until it is sent, I guess. Plus making sure the pollset for the transfer is probing the right direction.

@thomas-chauchefoin-tob

thomas-chauchefoin-tob commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

I can try to implement that, but it would have to wait for a few weeks. Should I keep this PR around or drop it?

@icing

icing commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Keep the PR, I think. We can merge this and then someone needs to find the time to do the non-blocking solution.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a busy-loop in the DICT protocol’s sendf() helper when Curl_xfer_send() reports a would-block condition as CURLE_OK with a zero-byte write. The updated loop now waits for socket writability and re-checks the remaining overall transfer time between retries, aligning DICT behavior with the existing approach used by gopher_do().

Changes:

  • Add timeout-aware retry behavior to sendf() by checking Curl_timeleft_ms() between partial/blocked sends.
  • Avoid 100% CPU spinning by waiting for socket writability via SOCKET_WRITABLE() when progress stalls.
  • Add the necessary internal headers (connect.h, select.h) to support the new logic.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@bagder

bagder commented Aug 14, 2026

Copy link
Copy Markdown
Member

Keep the PR, I think. We can merge this and then someone needs to find the time to do the non-blocking solution.

Yeah, I figure this is still a small step forward even if it can be improved further!

@bagder
bagder marked this pull request as ready for review August 14, 2026 08:11
@bagder bagder closed this in 68b5e60 Aug 14, 2026
@bagder

bagder commented Aug 14, 2026

Copy link
Copy Markdown
Member

Thanks!

@thomas-chauchefoin-tob

Copy link
Copy Markdown
Contributor Author

And the fuzzer coverage is back to normal with this patch; before vs after.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

4 participants