fix race condition in getConnsToClose

This commit is contained in:
Marten Seemann 2021-09-02 22:37:37 +01:00
parent 0ea56a8d6e
commit 4aeb0b901d
1 changed files with 7 additions and 8 deletions

View File

@ -318,15 +318,13 @@ func (cm *BasicConnMgr) getConnsToClose() []network.Conn {
return nil return nil
} }
nconns := int(atomic.LoadInt32(&cm.connCount)) if int(atomic.LoadInt32(&cm.connCount)) <= cm.cfg.lowWater {
if nconns <= cm.cfg.lowWater {
log.Info("open connection count below limit") log.Info("open connection count below limit")
return nil return nil
} }
npeers := cm.segments.countPeers() candidates := make([]peerInfo, 0, cm.segments.countPeers())
candidates := make([]*peerInfo, 0, npeers) var ncandidates int
ncandidates := 0
gracePeriodStart := time.Now().Add(-cm.cfg.gracePeriod) gracePeriodStart := time.Now().Add(-cm.cfg.gracePeriod)
cm.plk.RLock() cm.plk.RLock()
@ -341,7 +339,9 @@ func (cm *BasicConnMgr) getConnsToClose() []network.Conn {
// skip peers in the grace period. // skip peers in the grace period.
continue continue
} }
candidates = append(candidates, inf) // note that we're copying the entry here,
// but since inf.conns is a map, it will still point to the original object
candidates = append(candidates, *inf)
ncandidates += len(inf.conns) ncandidates += len(inf.conns)
} }
s.Unlock() s.Unlock()
@ -381,7 +381,6 @@ func (cm *BasicConnMgr) getConnsToClose() []network.Conn {
// lock this to protect from concurrent modifications from connect/disconnect events // lock this to protect from concurrent modifications from connect/disconnect events
s := cm.segments.get(inf.id) s := cm.segments.get(inf.id)
s.Lock() s.Lock()
if len(inf.conns) == 0 && inf.temp { if len(inf.conns) == 0 && inf.temp {
// handle temporary entries for early tags -- this entry has gone past the grace period // handle temporary entries for early tags -- this entry has gone past the grace period
// and still holds no connections, so prune it. // and still holds no connections, so prune it.
@ -390,8 +389,8 @@ func (cm *BasicConnMgr) getConnsToClose() []network.Conn {
for c := range inf.conns { for c := range inf.conns {
selected = append(selected, c) selected = append(selected, c)
} }
target -= len(inf.conns)
} }
target -= len(inf.conns)
s.Unlock() s.Unlock()
} }