mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Use embedded mutex pattern
PiperOrigin-RevId: 375728461
This commit is contained in:
committed by
gVisor bot
parent
38d158fe83
commit
d55f3a6b5e
+30
-35
@@ -323,26 +323,21 @@ type Rand interface {
|
||||
type NUDState struct {
|
||||
rng Rand
|
||||
|
||||
// mu protects the fields below.
|
||||
//
|
||||
// It is necessary for NUDState to handle its own locking since neighbor
|
||||
// entries may access the NUD state from within the goroutine spawned by
|
||||
// time.AfterFunc(). This goroutine may run concurrently with the main
|
||||
// process for controlling the neighbor cache and would otherwise introduce
|
||||
// race conditions if NUDState was not locked properly.
|
||||
mu sync.RWMutex
|
||||
mu struct {
|
||||
sync.RWMutex
|
||||
|
||||
config NUDConfigurations
|
||||
config NUDConfigurations
|
||||
|
||||
// reachableTime is the duration to wait for a REACHABLE entry to
|
||||
// transition into STALE after inactivity. This value is calculated with
|
||||
// the algorithm defined in RFC 4861 section 6.3.2.
|
||||
reachableTime time.Duration
|
||||
// reachableTime is the duration to wait for a REACHABLE entry to
|
||||
// transition into STALE after inactivity. This value is calculated with
|
||||
// the algorithm defined in RFC 4861 section 6.3.2.
|
||||
reachableTime time.Duration
|
||||
|
||||
expiration time.Time
|
||||
prevBaseReachableTime time.Duration
|
||||
prevMinRandomFactor float32
|
||||
prevMaxRandomFactor float32
|
||||
expiration time.Time
|
||||
prevBaseReachableTime time.Duration
|
||||
prevMinRandomFactor float32
|
||||
prevMaxRandomFactor float32
|
||||
}
|
||||
}
|
||||
|
||||
// NewNUDState returns new NUDState using c as configuration and the specified
|
||||
@@ -351,7 +346,7 @@ func NewNUDState(c NUDConfigurations, rng Rand) *NUDState {
|
||||
s := &NUDState{
|
||||
rng: rng,
|
||||
}
|
||||
s.config = c
|
||||
s.mu.config = c
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -359,14 +354,14 @@ func NewNUDState(c NUDConfigurations, rng Rand) *NUDState {
|
||||
func (s *NUDState) Config() NUDConfigurations {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
return s.config
|
||||
return s.mu.config
|
||||
}
|
||||
|
||||
// SetConfig replaces the existing NUD configurations with c.
|
||||
func (s *NUDState) SetConfig(c NUDConfigurations) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
s.config = c
|
||||
s.mu.config = c
|
||||
}
|
||||
|
||||
// ReachableTime returns the duration to wait for a REACHABLE entry to
|
||||
@@ -377,13 +372,13 @@ func (s *NUDState) ReachableTime() time.Duration {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if time.Now().After(s.expiration) ||
|
||||
s.config.BaseReachableTime != s.prevBaseReachableTime ||
|
||||
s.config.MinRandomFactor != s.prevMinRandomFactor ||
|
||||
s.config.MaxRandomFactor != s.prevMaxRandomFactor {
|
||||
if time.Now().After(s.mu.expiration) ||
|
||||
s.mu.config.BaseReachableTime != s.mu.prevBaseReachableTime ||
|
||||
s.mu.config.MinRandomFactor != s.mu.prevMinRandomFactor ||
|
||||
s.mu.config.MaxRandomFactor != s.mu.prevMaxRandomFactor {
|
||||
s.recomputeReachableTimeLocked()
|
||||
}
|
||||
return s.reachableTime
|
||||
return s.mu.reachableTime
|
||||
}
|
||||
|
||||
// recomputeReachableTimeLocked forces a recalculation of ReachableTime using
|
||||
@@ -408,23 +403,23 @@ func (s *NUDState) ReachableTime() time.Duration {
|
||||
//
|
||||
// s.mu MUST be locked for writing.
|
||||
func (s *NUDState) recomputeReachableTimeLocked() {
|
||||
s.prevBaseReachableTime = s.config.BaseReachableTime
|
||||
s.prevMinRandomFactor = s.config.MinRandomFactor
|
||||
s.prevMaxRandomFactor = s.config.MaxRandomFactor
|
||||
s.mu.prevBaseReachableTime = s.mu.config.BaseReachableTime
|
||||
s.mu.prevMinRandomFactor = s.mu.config.MinRandomFactor
|
||||
s.mu.prevMaxRandomFactor = s.mu.config.MaxRandomFactor
|
||||
|
||||
randomFactor := s.config.MinRandomFactor + s.rng.Float32()*(s.config.MaxRandomFactor-s.config.MinRandomFactor)
|
||||
randomFactor := s.mu.config.MinRandomFactor + s.rng.Float32()*(s.mu.config.MaxRandomFactor-s.mu.config.MinRandomFactor)
|
||||
|
||||
// Check for overflow, given that minRandomFactor and maxRandomFactor are
|
||||
// guaranteed to be positive numbers.
|
||||
if float32(math.MaxInt64)/randomFactor < float32(s.config.BaseReachableTime) {
|
||||
s.reachableTime = time.Duration(math.MaxInt64)
|
||||
if math.MaxInt64/randomFactor < float32(s.mu.config.BaseReachableTime) {
|
||||
s.mu.reachableTime = time.Duration(math.MaxInt64)
|
||||
} else if randomFactor == 1 {
|
||||
// Avoid loss of precision when a large base reachable time is used.
|
||||
s.reachableTime = s.config.BaseReachableTime
|
||||
s.mu.reachableTime = s.mu.config.BaseReachableTime
|
||||
} else {
|
||||
reachableTime := int64(float32(s.config.BaseReachableTime) * randomFactor)
|
||||
s.reachableTime = time.Duration(reachableTime)
|
||||
reachableTime := int64(float32(s.mu.config.BaseReachableTime) * randomFactor)
|
||||
s.mu.reachableTime = time.Duration(reachableTime)
|
||||
}
|
||||
|
||||
s.expiration = time.Now().Add(2 * time.Hour)
|
||||
s.mu.expiration = time.Now().Add(2 * time.Hour)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user