Skip to content

Commit

Permalink
transport: Fix deadlock in client keepalive. (grpc#1460)
Browse files Browse the repository at this point in the history
When gRPC keepalives are enabled (which isn't the case by default at
this time) and PermitWithoutStream is false (the default), the client
can deadlock when transitioning between having no active stream and
having one active stream.  Subsequent attempts to create a new stream
or to close the client will hang on the transport's mutex, while the
keepalive goroutine is waiting indefinitely on a channel while holding
the transport's mutex.

This fixes grpc#1459.
  • Loading branch information
tsuna authored and menghanl committed Aug 30, 2017
1 parent 537f644 commit 1fff120
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions transport/http2_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,10 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
select {
case t.awakenKeepalive <- struct{}{}:
t.framer.writePing(false, false, [8]byte{})
// Fill the awakenKeepalive channel again as this channel must be
// kept non-writable except at the point that the keepalive()
// goroutine is waiting either to be awaken or shutdown.
t.awakenKeepalive <- struct{}{}
default:
}
}
Expand Down

0 comments on commit 1fff120

Please sign in to comment.