From f7bbdc31a0065e3d5a68a3e6c7a7449954fdd339 Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Tue, 15 Dec 2020 17:44:21 -0800 Subject: device: fix data race in peer.timersActive Found by the race detector and existing tests. To avoid introducing a lock into this hot path, calculate and cache whether any peers exist. Signed-off-by: Josh Bleecher Snyder --- device/device.go | 6 ++++-- device/peer.go | 1 + device/timers.go | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/device/device.go b/device/device.go index 99f5e60..e7d70c4 100644 --- a/device/device.go +++ b/device/device.go @@ -49,8 +49,9 @@ type Device struct { } peers struct { - sync.RWMutex - keyMap map[NoisePublicKey]*Peer + empty AtomicBool // empty reports whether len(keyMap) == 0 + sync.RWMutex // protects keyMap + keyMap map[NoisePublicKey]*Peer } // unprotected / "self-synchronising resources" @@ -129,6 +130,7 @@ func unsafeRemovePeer(device *Device, peer *Peer, key NoisePublicKey) { // remove from peer map delete(device.peers.keyMap, key) + device.peers.empty.Set(len(device.peers.keyMap) == 0) } func deviceUpdateState(device *Device) { diff --git a/device/peer.go b/device/peer.go index fe6de33..73e6083 100644 --- a/device/peer.go +++ b/device/peer.go @@ -125,6 +125,7 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) { // add device.peers.keyMap[pk] = peer + device.peers.empty.Set(false) // start peer diff --git a/device/timers.go b/device/timers.go index e94da36..dbd4c66 100644 --- a/device/timers.go +++ b/device/timers.go @@ -73,7 +73,7 @@ func (timer *Timer) IsPending() bool { } func (peer *Peer) timersActive() bool { - return peer.isRunning.Get() && peer.device != nil && peer.device.isUp.Get() && len(peer.device.peers.keyMap) > 0 + return peer.isRunning.Get() && peer.device != nil && peer.device.isUp.Get() && !peer.device.peers.empty.Get() } func expiredRetransmitHandshake(peer *Peer) { -- cgit v1.2.3