Fix a deadlock in TransportSet.

Honor the lock order that transport lock > channel lock.

Resolves #2246
This commit is contained in:
Kun Zhang 2016-09-12 09:58:46 -07:00
parent 8b745d9114
commit 3d4ae36074
1 changed files with 6 additions and 1 deletions

View File

@ -249,9 +249,14 @@ final class TransportSet implements WithLogId {
delayedTransport.endBackoff();
boolean shutdownDelayedTransport = false;
Runnable runnable = null;
// TransportSet as a channel layer class should not call into transport methods while
// holding the lock, thus we call hasPendingStreams() outside of the lock. It will cause
// a _benign_ race where the TransportSet may transition to CONNECTING when there is not
// pending stream.
boolean hasPendingStreams = delayedTransport.hasPendingStreams();
synchronized (lock) {
reconnectTask = null;
if (delayedTransport.hasPendingStreams()) {
if (hasPendingStreams) {
// Transition directly to CONNECTING
runnable = startNewTransport(delayedTransport);
} else {