internal: fix GO_AWAY deadlock (#2391)

internal: fix GO_AWAY deadlock

A deadlock can occur when a GO_AWAY is followed by a connection closure. This
happens because onClose needlessly closes the current ac.transport: if a
GO_AWAY already occured, and the transport was already reset, then the later
closure (of the original address) sets ac.transport - which is now healthy -
to nil.

The manifestation of this problem is that picker_wrapper spins forever trying
to use a READY connection whose ac.transport is nil.
This commit is contained in:
Jean de Klerk
2018-10-19 14:11:21 -07:00
committed by GitHub
parent 39444b99c0
commit ff2aa05958
2 changed files with 109 additions and 3 deletions

View File

@ -1066,9 +1066,6 @@ func (ac *addrConn) createTransport(backoffNum int, addr resolver.Address, copts
case <-skipReset: // The outer resetTransport loop will handle reconnection.
return
case <-allowedToReset: // We're in the clear to reset.
ac.mu.Lock()
ac.transport = nil
ac.mu.Unlock()
oneReset.Do(func() { ac.resetTransport(false) })
}
}