From 5f059e74cb31c0c9a52a0dfde09dbc81beb5a07a Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Thu, 3 May 2018 15:45:22 -0700 Subject: [PATCH] peer: ensure msgConsumer sets the shutdown variable on exit In this commit, we fix a bug that could at times cause a deadlock when a peer is attempting to disconnect. The issue was that when a peer goes to disconnect, it needs to stop any active msgStream instances. The Stop() method of the msgStream would block until an atomic variable was set to indicate that the stream had fully exited. However, in the case that we disconnected lower in the msgConsumer loop, we would never set the streamShutdown variable, meaning that msgStream.Stop() would never unblock. The fix for this is simple: set the streamShutdown variable within the quit case of the second select statement in the msgConsumer goroutine. --- peer.go | 1 + 1 file changed, 1 insertion(+) diff --git a/peer.go b/peer.go index 248e5830..60c1c71a 100644 --- a/peer.go +++ b/peer.go @@ -637,6 +637,7 @@ func (ms *msgStream) msgConsumer() { select { case ms.producerSema <- struct{}{}: case <-ms.quit: + atomic.StoreInt32(&ms.streamShutdown, 1) return } }