diff options
author | Josh Bleecher Snyder <josh@tailscale.com> | 2020-12-15 17:44:21 -0800 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2021-01-07 14:49:44 +0100 |
commit | f7bbdc31a0065e3d5a68a3e6c7a7449954fdd339 (patch) | |
tree | b2605ff0dd0a12be4055d8b936abdb666a88ae9a /device/device.go | |
parent | 70861686d3005de91b45d38e5b16fd3132a4a872 (diff) |
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 <josh@tailscale.com>
Diffstat (limited to 'device/device.go')
-rw-r--r-- | device/device.go | 6 |
1 files changed, 4 insertions, 2 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) { |