|
@@ -50,6 +50,11 @@ type Session struct {
|
|
|
streams map[uint32]*Stream
|
|
|
streamLock sync.Mutex
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ synCh chan struct{}
|
|
|
+
|
|
|
|
|
|
acceptCh chan *Stream
|
|
|
|
|
@@ -85,6 +90,7 @@ func newSession(config *Config, conn io.ReadWriteCloser, client bool) *Session {
|
|
|
bufRead: bufio.NewReader(conn),
|
|
|
pings: make(map[uint32]chan struct{}),
|
|
|
streams: make(map[uint32]*Stream),
|
|
|
+ synCh: make(chan struct{}, config.AcceptBacklog),
|
|
|
acceptCh: make(chan *Stream, config.AcceptBacklog),
|
|
|
sendCh: make(chan sendReady, 64),
|
|
|
recvDoneCh: make(chan struct{}),
|
|
@@ -135,6 +141,13 @@ func (s *Session) OpenStream() (*Stream, error) {
|
|
|
return nil, ErrRemoteGoAway
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ select {
|
|
|
+ case s.synCh <- struct{}{}:
|
|
|
+ case <-s.shutdownCh:
|
|
|
+ return nil, ErrSessionShutdown
|
|
|
+ }
|
|
|
+
|
|
|
GET_ID:
|
|
|
|
|
|
id := atomic.LoadUint32(&s.nextStreamID)
|
|
@@ -152,7 +165,10 @@ GET_ID:
|
|
|
s.streamLock.Unlock()
|
|
|
|
|
|
|
|
|
- return stream, stream.sendWindowUpdate()
|
|
|
+ if err := stream.sendWindowUpdate(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return stream, nil
|
|
|
}
|
|
|
|
|
|
|
|
@@ -166,7 +182,10 @@ func (s *Session) Accept() (net.Conn, error) {
|
|
|
func (s *Session) AcceptStream() (*Stream, error) {
|
|
|
select {
|
|
|
case stream := <-s.acceptCh:
|
|
|
- return stream, stream.sendWindowUpdate()
|
|
|
+ if err := stream.sendWindowUpdate(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ return stream, nil
|
|
|
case <-s.shutdownCh:
|
|
|
return nil, s.shutdownErr
|
|
|
}
|
|
@@ -521,3 +540,13 @@ func (s *Session) closeStream(id uint32) {
|
|
|
delete(s.streams, id)
|
|
|
s.streamLock.Unlock()
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+func (s *Session) establishStream() {
|
|
|
+ select {
|
|
|
+ case <-s.synCh:
|
|
|
+ default:
|
|
|
+ panic("established stream without inflight syn")
|
|
|
+ }
|
|
|
+}
|