eliminate a deadlock

Golang locks aren't re-entrant. As result one can get deadlocks on
RWMutexes like this:

goroutine #1: attempt to acquire read lock -> success
goroutine #2: attempt to acquire write lock -> wait
goroutine #1: attempt to acquire read lock again -> wait

(a pending write lock prevents subsequent acquisitions of read locks)

Peer.HasPathTo could run into this since it could attempt to acquire
the read lock on a peer multiple times if previously it had
encountered that peer via an asymmetric connection.
This commit is contained in:
Matthias Radestock committed 2014-11-30 15:48:46 +00:00
1 parent 2680e594dd
commit 89a1e0fb24
1 file changed
+3 -1
+3 -1
View File
@@ -90,10 +90,12 @@ func (peer *Peer) HasPathTo(target *Peer, symmetric bool) (bool, map[PeerName]bo
// made to that path during our calculation.
remote := conn.Remote()
remote.RLock()
defer remote.RUnlock()
if _, found := remote.connections[curPeer.Name]; !symmetric || found {
defer remote.RUnlock()
nextWorklist = append(nextWorklist, remote)
reached[remoteName] = true
} else {
remote.RUnlock()
}
}
}