github.com/tumi8/quic-go@v0.37.4-tum/stream.go (about) 1 package quic 2 3 import ( 4 "net" 5 "os" 6 "sync" 7 "time" 8 9 "github.com/tumi8/quic-go/noninternal/ackhandler" 10 "github.com/tumi8/quic-go/noninternal/flowcontrol" 11 "github.com/tumi8/quic-go/noninternal/protocol" 12 "github.com/tumi8/quic-go/noninternal/wire" 13 ) 14 15 type deadlineError struct{} 16 17 func (deadlineError) Error() string { return "deadline exceeded" } 18 func (deadlineError) Temporary() bool { return true } 19 func (deadlineError) Timeout() bool { return true } 20 func (deadlineError) Unwrap() error { return os.ErrDeadlineExceeded } 21 22 var errDeadline net.Error = &deadlineError{} 23 24 // The streamSender is notified by the stream about various events. 25 type streamSender interface { 26 queueControlFrame(wire.Frame) 27 onHasStreamData(protocol.StreamID) 28 // must be called without holding the mutex that is acquired by closeForShutdown 29 onStreamCompleted(protocol.StreamID) 30 } 31 32 // Each of the both stream halves gets its own uniStreamSender. 33 // This is necessary in order to keep track when both halves have been completed. 34 type uniStreamSender struct { 35 streamSender 36 onStreamCompletedImpl func() 37 } 38 39 func (s *uniStreamSender) queueControlFrame(f wire.Frame) { 40 s.streamSender.queueControlFrame(f) 41 } 42 43 func (s *uniStreamSender) onHasStreamData(id protocol.StreamID) { 44 s.streamSender.onHasStreamData(id) 45 } 46 47 func (s *uniStreamSender) onStreamCompleted(protocol.StreamID) { 48 s.onStreamCompletedImpl() 49 } 50 51 var _ streamSender = &uniStreamSender{} 52 53 type streamI interface { 54 Stream 55 closeForShutdown(error) 56 // for receiving 57 handleStreamFrame(*wire.StreamFrame) error 58 handleResetStreamFrame(*wire.ResetStreamFrame) error 59 getWindowUpdate() protocol.ByteCount 60 // for sending 61 hasData() bool 62 handleStopSendingFrame(*wire.StopSendingFrame) 63 popStreamFrame(maxBytes protocol.ByteCount, v protocol.VersionNumber) (ackhandler.StreamFrame, bool, bool) 64 updateSendWindow(protocol.ByteCount) 65 } 66 67 var ( 68 _ receiveStreamI = (streamI)(nil) 69 _ sendStreamI = (streamI)(nil) 70 ) 71 72 // A Stream assembles the data from StreamFrames and provides a super-convenient Read-Interface 73 // 74 // Read() and Write() may be called concurrently, but multiple calls to Read() or Write() individually must be synchronized manually. 75 type stream struct { 76 receiveStream 77 sendStream 78 79 completedMutex sync.Mutex 80 sender streamSender 81 receiveStreamCompleted bool 82 sendStreamCompleted bool 83 } 84 85 var _ Stream = &stream{} 86 87 // newStream creates a new Stream 88 func newStream(streamID protocol.StreamID, 89 sender streamSender, 90 flowController flowcontrol.StreamFlowController, 91 ) *stream { 92 s := &stream{sender: sender} 93 senderForSendStream := &uniStreamSender{ 94 streamSender: sender, 95 onStreamCompletedImpl: func() { 96 s.completedMutex.Lock() 97 s.sendStreamCompleted = true 98 s.checkIfCompleted() 99 s.completedMutex.Unlock() 100 }, 101 } 102 s.sendStream = *newSendStream(streamID, senderForSendStream, flowController) 103 senderForReceiveStream := &uniStreamSender{ 104 streamSender: sender, 105 onStreamCompletedImpl: func() { 106 s.completedMutex.Lock() 107 s.receiveStreamCompleted = true 108 s.checkIfCompleted() 109 s.completedMutex.Unlock() 110 }, 111 } 112 s.receiveStream = *newReceiveStream(streamID, senderForReceiveStream, flowController) 113 return s 114 } 115 116 // need to define StreamID() here, since both receiveStream and readStream have a StreamID() 117 func (s *stream) StreamID() protocol.StreamID { 118 // the result is same for receiveStream and sendStream 119 return s.sendStream.StreamID() 120 } 121 122 func (s *stream) Close() error { 123 return s.sendStream.Close() 124 } 125 126 func (s *stream) SetDeadline(t time.Time) error { 127 _ = s.SetReadDeadline(t) // SetReadDeadline never errors 128 _ = s.SetWriteDeadline(t) // SetWriteDeadline never errors 129 return nil 130 } 131 132 // CloseForShutdown closes a stream abruptly. 133 // It makes Read and Write unblock (and return the error) immediately. 134 // The peer will NOT be informed about this: the stream is closed without sending a FIN or RST. 135 func (s *stream) closeForShutdown(err error) { 136 s.sendStream.closeForShutdown(err) 137 s.receiveStream.closeForShutdown(err) 138 } 139 140 // checkIfCompleted is called from the uniStreamSender, when one of the stream halves is completed. 141 // It makes sure that the onStreamCompleted callback is only called if both receive and send side have completed. 142 func (s *stream) checkIfCompleted() { 143 if s.sendStreamCompleted && s.receiveStreamCompleted { 144 s.sender.onStreamCompleted(s.StreamID()) 145 } 146 }