MarshallOfSound

#53341: fix: settle pending upload stream reads when a net.request ends

Merged
Created: Aug 31, 2026, 1:20:46 PM
Merged: Sep 1, 2026, 10:31:43 AM
8 comments
Target: main

Description of Change

  • net.request never told its chunked upload getter when the request ended. A protocol handler that had parked a body.read() on the upload stream then waited forever for a GetSize reply that could not come, and the stream's SelfKeepAlive kept it rooted. SimpleURLLoaderWrapper::OnComplete and Cancel now abort the getter, so the pending read rejects with the request's net error.
  • This is the cause of the cpp heap url loader module keeps a ChunkedDataPipeReadableStream alive … hang seen on the ASan and UBSan shard-3 jobs (three unrelated PRs on 2026-08-31, e.g. this run). That test's handler never responds and drops the one-time callback; the native side only references it weakly (gin_helper/callback.cc), so the test's own GC loop could collect it, which fails the request with ERR_FAILED before request.end() runs. Whether the GC caught it in time is timing-dependent, hence the flake. The handler now holds the callback for the test's duration.
  • New api-net-spec cases: a handler parks an upload-stream read and the request is aborted or failed (the read rejects with ERR_FAILED), and a response completes while a write is still in flight (the write callback gets ERR_ABORTED).
  • The first CI run of this PR hit an ASan use-after-poison in mojo::ReceiverSetState::Entry::OnDisconnect. With poison_history_size on, ASan attributes the poison to cppgc's UnmarkedObjectsPoisoner at the start of a sweep: a SimpleURLLoaderWrapper had been found dead but not yet finalized when the network service's disconnect for one of its observer receivers arrived. UtilityProcessWrapper has the same ReceiverSet shape. Both now get a cppgc pre-finalizer that drops the receivers before the sweep, as ReplyChannel and the IPC renderer classes already do. Locally the 28-file ASan shard reproduced the crash on the first version and runs clean with this one.

Verified locally on an ASan build: the original cpp-heap spec failed 3/3 before and passes after, a standalone repro with the callback still collectable completes instead of hanging, and the new net specs pass.

Checklist

Release Notes

Notes: Fixed a pending read on a net.request chunked upload stream inside a protocol handler never settling when the request failed or was aborted.

Backports

43-x-y
In-flight
PR Number
#53374
Waiting to be merged
44-x-y
In-flight
PR Number
#53373
Waiting to be merged
45-x-y
In-flight
PR Number
#53368
Waiting to be merged

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

Semantic Versioning helps users understand the impact of updates:

  • Major (X.y.z): Breaking changes that may require code modifications
  • Minor (x.Y.z): New features that maintain backward compatibility
  • Patch (x.y.Z): Bug fixes that don't change the API
  • None: Changes that don't affect using facing parts of Electron