* simplify timer resets
As of Go 1.23, timer resets work as expected, and there’s no need to
read a (potentially) stale value from the timer channel.
* don't save the last time
* track if blocked
* remove unblock after sendingScheduled
* fix unblock logic when sending
* don't use fallthrough
* track the blocking mode
* remove stale comment
* implement a memory-optimized time.Time replacement
* monotime: properly handle systems with bad timer resolution (Windows)
* monotime: simplify Since
* fix: return stream frames to pool on error paths
fixes potential memory leak where StreamFrames were not returned to
sync.Pool in error/cancellation paths.
root cause: frames are llocated via GetStreamFrame() but never returned
via PutBack() when streams enter terminal states without going through
normal OnAcked() cleanup.
fixed paths:
- CancelWrite(): return frames when reliableOffset == 0
- handleStopSendingFrame(): return frames on STOP_SENDING
- closeForShutdown(): return frames on connection shutdown
- OnLost(): return frame when stream reset with no data sent
* fix: clear slice before nil assignment, remove excessive tests
- add clear() call to properly release GC references per https://github.com/quic-go/quic-go/pull/5327#discussion_r2328451862
- remove excessive pool return tests per https://github.com/quic-go/quic-go/pull/5327#discussion_r2328453227
* improve existing send stream test
* implement sender side behavior for RESET_STREAM_AT
* refactor send stream cancelation and shutdown error handling
* correctly deal with 0-RTT corner case
* preserve error from cancelled SendStream during cancellation and closing
* clarify that canceling a send stream after closing is valid
* preserve close and reset error when send stream is closed for shutdown
* refactor the framer to pack both control and STREAM frames
* refactor framer STREAM frame packing logic
* pack STREAM_DATA_BLOCKED in the same packet as the STREAM frame
This makes debugging easier (and is slightly more efficient). In the
pathological case where there is not enough space remaning in the packet
to pack the STREAM_DATA_BLOCKED frame, it is queued for the next packet.
* add an integration test
This ensures that `stream.Write` and `stream.Read` return the error code
from connection close, if the stream was closed as a result of
connection close.
* garbage collect stream when CancelWrite is called after receiving STOP_SENDING
* review comments
* Hold lock while checking isNewlyCompleted
---------
Co-authored-by: Marco Munizaga <git@marcopolo.io>
* avoid accessing the streams map when packing stream data
* avoid accessing the streams map when packing flow control frames
* remove streamGetter interface
The connection already cancels the base context, so we don't need to manually
cancel the stream context (which is derived from the connection context).
* delay completion of the send stream until the reset error was delivered
* mark the send stream completed on Close after receiving a STOP_SENDING
* fix handling of STOP_SENDING after Close
* remove the closedForShutdown boolean in the send stream
* remove the canceledWrite boolean in the send stream
* remove the closedForShutdown boolean in the receive stream
* remove the canceledRead boolean in the receive stream
* remove the resetRemotely boolean in the receive stream
* optimize memory layout of the receiveStream
This brings it down from 200 to 192 bytes.
* fix: return typed errors when after cancelling actions
This is errors.Is'ed by libp2p and the fmt.Errorf messages didn't passed that test:
82315917f7/p2p/transport/quic/stream.go (L23)
* replace StreamErrorAction with a local / remote flag
Co-authored-by: Jorropo <jorropo.pgm@gmail.com>
If the complete slice passed to Stream.Write() is sent out, and the
stream is canceled concurrently (either by calling Stream.CancelWrite()
or by receiving a STOP_SENDING frame), we don't need to return an error
for the Write() call.