Преглед на файлове

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 преди 10 години
родител
ревизия
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
 	// once we get to here we know that the caller must be waiting and that there
 	// is no error.
 	// is no error.
 	call.resp <- nil
 	call.resp <- nil
-	c.uniq <- head.stream
 
 
 	return nil
 	return nil
 }
 }
@@ -337,9 +336,17 @@ type callReq struct {
 	framer *framer
 	framer *framer
 }
 }
 
 
+func (c *Conn) releaseStream(stream int) {
+	select {
+	case c.uniq <- stream:
+	default:
+	}
+}
+
 func (c *Conn) exec(req frameWriter, tracer Tracer) (frame, error) {
 func (c *Conn) exec(req frameWriter, tracer Tracer) (frame, error) {
 	// TODO: move tracer onto conn
 	// TODO: move tracer onto conn
 	stream := <-c.uniq
 	stream := <-c.uniq
+	defer c.releaseStream(stream)
 
 
 	call := &c.calls[stream]
 	call := &c.calls[stream]
 	// resp is basically a waiting semaphore protecting the framer
 	// resp is basically a waiting semaphore protecting the framer