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