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>
This commit is contained in:
parent
70861686d3
commit
f7bbdc31a0
|
@ -49,7 +49,8 @@ type Device struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
peers struct {
|
peers struct {
|
||||||
sync.RWMutex
|
empty AtomicBool // empty reports whether len(keyMap) == 0
|
||||||
|
sync.RWMutex // protects keyMap
|
||||||
keyMap map[NoisePublicKey]*Peer
|
keyMap map[NoisePublicKey]*Peer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +130,7 @@ func unsafeRemovePeer(device *Device, peer *Peer, key NoisePublicKey) {
|
||||||
// remove from peer map
|
// remove from peer map
|
||||||
|
|
||||||
delete(device.peers.keyMap, key)
|
delete(device.peers.keyMap, key)
|
||||||
|
device.peers.empty.Set(len(device.peers.keyMap) == 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deviceUpdateState(device *Device) {
|
func deviceUpdateState(device *Device) {
|
||||||
|
|
|
@ -125,6 +125,7 @@ func (device *Device) NewPeer(pk NoisePublicKey) (*Peer, error) {
|
||||||
// add
|
// add
|
||||||
|
|
||||||
device.peers.keyMap[pk] = peer
|
device.peers.keyMap[pk] = peer
|
||||||
|
device.peers.empty.Set(false)
|
||||||
|
|
||||||
// start peer
|
// start peer
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ func (timer *Timer) IsPending() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (peer *Peer) timersActive() 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) {
|
func expiredRetransmitHandshake(peer *Peer) {
|
||||||
|
|
Loading…
Reference in a new issue