s.errorRead = true
return false, false, 0, io.EOF
}
- if s.cancelledLocally || (s.cancelledRemotely && s.readPos >= s.reliableSize) {
+ if s.cancelledLocally || s.isRemoteCancellationEffective() {
s.errorRead = true
return false, false, 0, s.cancelErr
}
if s.closeForShutdownErr != nil {
return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.closeForShutdownErr
}
- if s.cancelledLocally || (s.cancelledRemotely && s.readPos >= s.reliableSize) {
+ if s.cancelledLocally || s.isRemoteCancellationEffective() {
s.errorRead = true
return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.cancelErr
}
deadline := s.deadline
- if !deadline.IsZero() {
- if !monotime.Now().Before(deadline) {
- return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, errDeadline
- }
- if deadlineTimer == nil {
- deadlineTimer = time.NewTimer(monotime.Until(deadline))
- defer deadlineTimer.Stop()
- } else {
- deadlineTimer.Reset(monotime.Until(deadline))
- }
+ if !deadline.IsZero() && !monotime.Now().Before(deadline) {
+ return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, errDeadline
}
if s.currentFrame != nil || s.currentFrameIsLast {
if deadline.IsZero() {
<-s.readChan
} else {
+ if deadlineTimer == nil {
+ deadlineTimer = time.NewTimer(monotime.Until(deadline))
+ defer deadlineTimer.Stop()
+ } else {
+ deadlineTimer.Reset(monotime.Until(deadline))
+ }
select {
case <-s.readChan:
case <-deadlineTimer.C:
}
}
s.mutex.Lock()
- if s.currentFrame == nil {
- s.dequeueNextFrame()
- }
+ s.dequeueNextFrame()
}
if bytesRead > len(p) {
// when a RESET_STREAM was received, the flow controller was already
// informed about the final offset for this stream
- if !s.cancelledRemotely || s.readPos < s.reliableSize {
+ if !s.isRemoteCancellationEffective() {
hasStream, hasConn := s.flowController.AddBytesRead(protocol.ByteCount(m))
if hasStream {
s.queuedMaxStreamData = true
s.readPos += protocol.ByteCount(m)
bytesRead += m
- if s.cancelledRemotely && s.readPos >= s.reliableSize {
+ if s.isRemoteCancellationEffective() {
s.flowController.Abandon()
}
return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, io.EOF
}
}
- if s.cancelledRemotely && s.readPos >= s.reliableSize {
+ if s.isRemoteCancellationEffective() {
s.errorRead = true
return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, s.cancelErr
}
return hasStreamWindowUpdate, hasConnWindowUpdate, bytesRead, nil
}
+// isRemoteCancellationEffective returns whether the stream was cancelled remotely
+// and all reliable data has been read.
+func (s *ReceiveStream) isRemoteCancellationEffective() bool {
+ return s.cancelledRemotely && s.readPos >= s.reliableSize
+}
+
func (s *ReceiveStream) dequeueNextFrame() {
var offset protocol.ByteCount
// We're done with the last frame. Release the buffer.