Skip to content

fix(h3): defer a drain requested from inside ngtcp2's packet read (#428) - #429

Merged
EdmondDantes merged 2 commits into
mainfrom
fix/428-h3-ondone-in-callback
Oct 20, 2026
Merged

EdmondDantes merged 2 commits into
mainfrom
fix/428-h3-ondone-in-callback

Conversation

@EdmondDantes

Copy link
Copy Markdown
Contributor

Fixes #428.

A static or sendFile() response on HTTP/3 finishes when nghttp3 closes its stream, which happens inside ngtcp2_conn_read_pkt while an ACK is processed. The dispose tail then called http3_connection_drain_out → ngtcp2_conn_writev_stream, which ngtcp2.h forbids from a callback, and could re-enter a drain in progress.

  • http3_connection_t.in_read_pkt is set around the one ngtcp2_conn_read_pkt call.
  • http3_connection_drain_out called while it is set marks the connection (http3_listener_mark_flush + http3_listener_request_flush) and returns; the read path flushes it after the datagram. Inside a poll tick or a reactor drain the request only links the listener, so h3/101 and h3/102 still read 0 flush wakes.
  • Debug assertions of the same condition stay before the writev loop and before ngtcp2_conn_write_connection_close.

Evidence (ZTS DEBUG, local): with only the assertion, 9 h3 tests fail (039, 052, 053, 054, 090, 091, 099, 101, 102); with the deferral, full phpt 629 passed, 2 skipped, 0 failed; cmocka 24 of 24.

Also: dev/PLAN.md closes stage S6 (#412) and queues #428 and #426.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage

Total lines: 85.89% → 85.92% (+0.03 pp)

File Baseline Current Δ Touched
src/core/thread_queue.cc 80.33% 81.15% +0.82 pp
src/http3/http3_connection.c 86.39% 86.45% +0.07 pp ●
src/http3/http3_io.c 89.09% 89.68% +0.59 pp ●
src/http3/http3_listener.c 79.07% 79.92% +0.84 pp

@EdmondDantes
EdmondDantes merged commit ebc1f1f into main Oct 20, 2026
8 checks passed
@EdmondDantes
EdmondDantes deleted the fix/428-h3-ondone-in-callback branch October 20, 2026 07:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTTP/3: a finished static or sendFile transfer writes packets from inside an ngtcp2 callback

1 participant