@@ -82,6 +82,7 @@ type Connection struct {
8282// Connection.
8383type inFlightState struct {
8484 connClosing bool // true when the Connection's Close method has been called
85+ reading bool // true while the readIncoming goroutine is running
8586 readErr error // non-nil when the readIncoming goroutine exits (typically io.EOF)
8687 writeErr error // non-nil if a call to the Writer has failed with a non-canceled Context
8788
@@ -140,14 +141,13 @@ func (c *Connection) updateInFlight(f func(*inFlightState)) {
140141 s .closeErr = s .closer .Close ()
141142 s .closer = nil // prevent duplicate Close calls
142143 }
143- if s .readErr == nil {
144+ if s .reading {
144145 // The readIncoming goroutine is still running. Our call to Close should
145146 // cause it to exit soon, at which point it will make another call to
146- // updateInFlight, set s.readErr to a non-nil error, and mark the
147- // Connection done.
147+ // updateInFlight, set s.reading to false, and mark the Connection done.
148148 } else {
149- // The readIncoming goroutine has exited. Since everything else is idle,
150- // we're completely done.
149+ // The readIncoming goroutine has exited, or never started to begin with.
150+ // Since everything else is idle, we're completely done.
151151 if c .onDone != nil {
152152 c .onDone ()
153153 }
@@ -240,10 +240,18 @@ func newConnection(bindCtx context.Context, rwc io.ReadWriteCloser, binder Binde
240240 reader := framer .Reader (rwc )
241241
242242 c .updateInFlight (func (s * inFlightState ) {
243+ select {
244+ case <- c .done :
245+ // Bind already closed the connection; don't start a goroutine to read it.
246+ return
247+ default :
248+ }
249+
243250 // The goroutine started here will continue until the underlying stream is closed.
244251 //
245252 // (If the Binder closed the Connection already, this should error out and
246253 // return almost immediately.)
254+ s .reading = true
247255 go c .readIncoming (ctx , reader , options .Preempter )
248256 })
249257 return c
@@ -514,6 +522,7 @@ func (c *Connection) readIncoming(ctx context.Context, reader Reader, preempter
514522 }
515523
516524 c .updateInFlight (func (s * inFlightState ) {
525+ s .reading = false
517526 s .readErr = err
518527
519528 // Retire any outgoing requests that were still in flight: with the Reader no
0 commit comments