Skip to content

Commit

Permalink
transport: Fix deadlock in client keepalive. (#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 #1459.
  • Loading branch information
tsuna authored and MakMukhi committed Aug 25, 2017
1 parent 7db1564 commit c29d638
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 c29d638

Please sign in to comment.