// This file was automatically generated by genny. // Any changes will be lost if this file is regenerated. // see https://github.com/cheekybits/genny package quic import ( "sync" "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/wire" ) type outgoingUniStreamsMap struct { mutex sync.RWMutex cond sync.Cond streams map[protocol.StreamNum]sendStreamI nextStream protocol.StreamNum // stream ID of the stream returned by OpenStream(Sync) maxStream protocol.StreamNum // the maximum stream ID we're allowed to open blockedSent bool // was a STREAMS_BLOCKED sent for the current maxStream newStream func(protocol.StreamNum) sendStreamI queueStreamIDBlocked func(*wire.StreamsBlockedFrame) closeErr error } func newOutgoingUniStreamsMap( newStream func(protocol.StreamNum) sendStreamI, queueControlFrame func(wire.Frame), ) *outgoingUniStreamsMap { m := &outgoingUniStreamsMap{ streams: make(map[protocol.StreamNum]sendStreamI), maxStream: protocol.InvalidStreamNum, nextStream: 1, newStream: newStream, queueStreamIDBlocked: func(f *wire.StreamsBlockedFrame) { queueControlFrame(f) }, } m.cond.L = &m.mutex return m } func (m *outgoingUniStreamsMap) OpenStream() (sendStreamI, error) { m.mutex.Lock() defer m.mutex.Unlock() if m.closeErr != nil { return nil, m.closeErr } str, err := m.openStreamImpl() if err != nil { return nil, streamOpenErr{err} } return str, nil } func (m *outgoingUniStreamsMap) OpenStreamSync() (sendStreamI, error) { m.mutex.Lock() defer m.mutex.Unlock() for { if m.closeErr != nil { return nil, m.closeErr } str, err := m.openStreamImpl() if err == nil { return str, nil } if err != nil && err != errTooManyOpenStreams { return nil, streamOpenErr{err} } m.cond.Wait() } } func (m *outgoingUniStreamsMap) openStreamImpl() (sendStreamI, error) { if m.nextStream > m.maxStream { if !m.blockedSent { var streamNum protocol.StreamNum if m.maxStream != protocol.InvalidStreamNum { streamNum = m.maxStream } m.queueStreamIDBlocked(&wire.StreamsBlockedFrame{ Type: protocol.StreamTypeUni, StreamLimit: streamNum, }) m.blockedSent = true } return nil, errTooManyOpenStreams } s := m.newStream(m.nextStream) m.streams[m.nextStream] = s m.nextStream++ return s, nil } func (m *outgoingUniStreamsMap) GetStream(num protocol.StreamNum) (sendStreamI, error) { m.mutex.RLock() if num >= m.nextStream { m.mutex.RUnlock() return nil, streamError{ message: "peer attempted to open stream %d", nums: []protocol.StreamNum{num}, } } s := m.streams[num] m.mutex.RUnlock() return s, nil } func (m *outgoingUniStreamsMap) DeleteStream(num protocol.StreamNum) error { m.mutex.Lock() defer m.mutex.Unlock() if _, ok := m.streams[num]; !ok { return streamError{ message: "Tried to delete unknown stream %d", nums: []protocol.StreamNum{num}, } } delete(m.streams, num) return nil } func (m *outgoingUniStreamsMap) SetMaxStream(num protocol.StreamNum) { m.mutex.Lock() if num > m.maxStream { m.maxStream = num m.blockedSent = false m.cond.Broadcast() } m.mutex.Unlock() } func (m *outgoingUniStreamsMap) CloseWithError(err error) { m.mutex.Lock() m.closeErr = err for _, str := range m.streams { str.closeForShutdown(err) } m.cond.Broadcast() m.mutex.Unlock() }