소스 검색

Fix a potential race when releasing streams

The caller in exec will reuse the streamID in uniq, ensure that
the stream is only available for use after the caller is done
with it.
Chris Bannister 11 년 전
부모
커밋
a167fd8da3
1개의 변경된 파일8개의 추가작업 그리고 1개의 파일을 삭제
  1. 8 1
      conn.go

+ 8 - 1
conn.go

@@ -326,7 +326,6 @@ func (c *Conn) recv() error {
 	// once we get to here we know that the caller must be waiting and that there
 	// is no error.
 	call.resp <- nil
-	c.uniq <- head.stream
 
 	return nil
 }
@@ -337,9 +336,17 @@ type callReq struct {
 	framer *framer
 }
 
+func (c *Conn) releaseStream(stream int) {
+	select {
+	case c.uniq <- stream:
+	default:
+	}
+}
+
 func (c *Conn) exec(req frameWriter, tracer Tracer) (frame, error) {
 	// TODO: move tracer onto conn
 	stream := <-c.uniq
+	defer c.releaseStream(stream)
 
 	call := &c.calls[stream]
 	// resp is basically a waiting semaphore protecting the framer