pub enum H2WriteTarget {
Done(MuxResult),
Transmit {
stream_id: H2StreamId,
},
Finalize {
socket_write: bool,
bytes_written: usize,
},
}Expand description
What ConnectionH2::poll_write_target wants its caller to do before it
may call ConnectionH2::handle_write.
The write half of H2ReadTarget’s protocol, with ONE forced divergence:
a readable() pass performs exactly one socket_read, so the read side is
a two-call protocol that ENDS with handle_read. A write pass performs an
unbounded number of socket_write_vectored calls — the pre-image’s
while !kawa.out.is_empty() inside a loop over the scheduler’s order — so
the write side is a DRIVE LOOP. ConnectionH2::handle_write settles one
transmit and answers nothing; the pass’s result comes from Self::Done
or from the ConnectionH2::finalize_write the caller runs for
Self::Finalize.
Variants§
Done(MuxResult)
The core ended the pass by itself. No write, no
ConnectionH2::handle_write, and no finalize — this is the pass’s
result.
Two sites, and neither may become a Self::Finalize: the resume
path’s stall and the MadeYouReset emitted-RST cap trip. Folding either
into Finalize would run
LIFECYCLE §9 invariant 16’s readiness policy over a pass that must not
reach it.
Transmit
Gather stream_id’s queued blocks with h2_transmit::gather, hand
the descriptors to socket_write_vectored, discharge them with
h2_transmit::confirm, then answer with
ConnectionH2::handle_write.
stream_id is never H2StreamId::Zero: self.zero is input only,
the resume phase parks and matches H2StreamId::Other only, and the
scheduler loop walks real stream ids. The transmit sends the ordered
output queue first (ConnectionH2::gather_transmit), so the rest of a
frame an earlier write cut always leaves ahead of the next frame.
Fields
stream_id: H2StreamIdFinalize
The pass is over and owes the readiness decision of LIFECYCLE §9
invariant 16. Read H2Shell::tls_wants_write, hand it to
ConnectionH2::finalize_write alongside socket_write and
bytes_written, and drive the H2FinalizeTarget that answers; the
end of that protocol is the pass’s result.
bytes_written rides along with socket_write because
finalize_write reads it as made_progress, and that is what selects
FinalizeAction::RetainPendingBack over Quiesce. It is accumulated
stream by stream inside the loop, so only the pass knows it.