@@ -82,6 +82,7 @@ type Connection struct {
82
82
// Connection.
83
83
type inFlightState struct {
84
84
connClosing bool // true when the Connection's Close method has been called
85
+ reading bool // true while the readIncoming goroutine is running
85
86
readErr error // non-nil when the readIncoming goroutine exits (typically io.EOF)
86
87
writeErr error // non-nil if a call to the Writer has failed with a non-canceled Context
87
88
@@ -140,14 +141,13 @@ func (c *Connection) updateInFlight(f func(*inFlightState)) {
140
141
s .closeErr = s .closer .Close ()
141
142
s .closer = nil // prevent duplicate Close calls
142
143
}
143
- if s .readErr == nil {
144
+ if s .reading {
144
145
// The readIncoming goroutine is still running. Our call to Close should
145
146
// 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.
148
148
} 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.
151
151
if c .onDone != nil {
152
152
c .onDone ()
153
153
}
@@ -240,10 +240,18 @@ func newConnection(bindCtx context.Context, rwc io.ReadWriteCloser, binder Binde
240
240
reader := framer .Reader (rwc )
241
241
242
242
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
+
243
250
// The goroutine started here will continue until the underlying stream is closed.
244
251
//
245
252
// (If the Binder closed the Connection already, this should error out and
246
253
// return almost immediately.)
254
+ s .reading = true
247
255
go c .readIncoming (ctx , reader , options .Preempter )
248
256
})
249
257
return c
@@ -514,6 +522,7 @@ func (c *Connection) readIncoming(ctx context.Context, reader Reader, preempter
514
522
}
515
523
516
524
c .updateInFlight (func (s * inFlightState ) {
525
+ s .reading = false
517
526
s .readErr = err
518
527
519
528
// Retire any outgoing requests that were still in flight: with the Reader no
0 commit comments