From 7ec9c8e110b96aecc5b1ee345095630c769b87f2 Mon Sep 17 00:00:00 2001 From: William Banfield Date: Mon, 4 Oct 2021 17:54:34 -0400 Subject: [PATCH] wait in lock --- internal/consensus/reactor.go | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/internal/consensus/reactor.go b/internal/consensus/reactor.go index a842f1a1f..22bd7576e 100644 --- a/internal/consensus/reactor.go +++ b/internal/consensus/reactor.go @@ -229,27 +229,16 @@ func (r *Reactor) OnStop() { r.state.Wait() } - peers := make(map[types.NodeID]*PeerState) r.mtx.Lock() - - // Here, we make a copy of the map of peer states. - // The code below proceeds to access entries from the map outside of a lock. - // Goroutines launched by other functions may be deleting from the map but should - // no longer be appending to it since we waited for the peerUpdates channel to complete. - // Each of the methods below is safe to perform concurrently on the peers. - for id, state := range r.peers { - peers[id] = state + // Close and wait for each of the peers to shutdown. + // This is safe to perform with the lock since none of the peers require the + // lock to complete any of the methods that the waitgroup is waiting on. + for _, state := range r.peers { + state.closer.Close() + state.broadcastWG.Wait() } r.mtx.Unlock() - // wait for all spawned peer goroutines to gracefully exit - for _, ps := range peers { - ps.closer.Close() - } - for _, ps := range peers { - ps.broadcastWG.Wait() - } - // Close the StateChannel goroutine separately since it uses its own channel // to signal closure. close(r.stateCloseCh)