Skip to content

cw-out: avoid O(n^2) work while buffering paused output - #22896

Closed
MegaManSec wants to merge 3 commits into
curl:masterfrom
MegaManSec:worktree-agent-a95e90134320b488b
Closed

MegaManSec wants to merge 3 commits into
curl:masterfrom
MegaManSec:worktree-agent-a95e90134320b488b

Conversation

@MegaManSec

@MegaManSec MegaManSec commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Improves paused-output buffer performance without changing protocol behavior.

The buffer chain now keeps a tail pointer, so appending does not repeatedly walk the list, and tracks the total buffered length instead of rescanning every buffer on each append. Flushing proceeds from the oldest buffer iteratively.

This reduces buffering many paused writes from quadratic list/replay bookkeeping to linear work.

When a header callback returns CURL_WRITEFUNC_PAUSE, cw_out_do_write
downgraded the resulting CURLE_AGAIN to CURLE_OK, so the HTTP/2 layer
kept feeding it every remaining decoded header field in the current
HPACK block instead of stopping. on_header() now returns
NGHTTP2_ERR_PAUSE while paused, nghttp2's documented mechanism to halt
decoding mid-block, and the pending-input loop breaks on pause too.

Separately, the pause buffer's cw_out_buf chain was a stack replayed
via recursive tail-hunting, and its buffered length was recomputed by
a full list walk on every append: both O(n^2) over the chain. Track a
tail pointer and a running length instead.
@icing

icing commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

As I understand it, NGHTTP2_ERR_PAUSE pauses the whole connection, not only a single stream? If so, that is not what we want to go for.

@MegaManSec

Copy link
Copy Markdown
Contributor Author

Right, let's get rid of that and just keep this pr focused on one thing (the perf bump attempt). Will chahge

@MegaManSec MegaManSec changed the title http2: honor header-callback pause, fix O(n^2) header buffering cw-out: avoid O(n^2) work while buffering paused output Sep 10, 2026
@MegaManSec

Copy link
Copy Markdown
Contributor Author

Updated as discussed: removed the HTTP/2 pause behavior changes. This PR now focuses only on the cw-out paused-buffer performance improvement.

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.

🟢 Approval recommended

The queue invariants, byte accounting, cleanup, and output ordering remain correct.

Pull request overview

Optimizes paused-output buffering while preserving FIFO callback behavior.

Changes:

  • Adds constant-time tail insertion and buffered-length tracking.
  • Replaces recursive reverse-list flushing with iterative oldest-first flushing.
File summaries
File Description
lib/cw-out.c Optimizes buffer append, size accounting, cleanup, and flushing.
Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 0
  • Review effort level: Balanced

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

@bagder bagder closed this in 89ca8fe Sep 11, 2026
@bagder

bagder commented Sep 11, 2026

Copy link
Copy Markdown
Member

Thanks!

@MegaManSec
MegaManSec deleted the worktree-agent-a95e90134320b488b branch September 14, 2026 09:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants