mirror of
https://github.com/tailscale/tailscale.git
synced 2024-11-29 04:55:31 +00:00
wgengine/monitor: do not set timeJumped on iOS/Android
In `(*Mon).Start` we don't run a timer to update `(*Mon).lastWall` on iOS and Android as their sleep patterns are bespoke. However, in the debounce goroutine we would notice that the the wall clock hadn't been updated since the last event would assume that a time jump had occurred. This would result in non-events being considered as major-change events. This commit makes it so that `(*Mon).timeJumped` is never set to `true` on iOS and Android. Signed-off-by: Maisem Ali <maisem@tailscale.com>
This commit is contained in:
parent
ade7bd8745
commit
3ffd88a84a
@ -185,13 +185,7 @@ func (m *Mon) Start() {
|
||||
}
|
||||
m.started = true
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "ios", "android":
|
||||
// For battery reasons, and because these platforms
|
||||
// don't really sleep in the same way, don't poll
|
||||
// for the wall time to detect for wake-for-sleep
|
||||
// walltime jumps.
|
||||
default:
|
||||
if shouldMonitorTimeJump {
|
||||
m.wallTimer = time.AfterFunc(pollWallTimeInterval, m.pollWallTime)
|
||||
}
|
||||
|
||||
@ -304,16 +298,9 @@ func (m *Mon) debounce() {
|
||||
} else {
|
||||
m.mu.Lock()
|
||||
|
||||
// See if we have a queued or new time jump signal.
|
||||
m.checkWallTimeAdvanceLocked()
|
||||
timeJumped := m.timeJumped
|
||||
if timeJumped {
|
||||
m.logf("time jumped (probably wake from sleep); synthesizing major change event")
|
||||
}
|
||||
|
||||
oldState := m.ifState
|
||||
ifChanged := !curState.EqualFiltered(oldState, interfaces.UseInterestingInterfaces, interfaces.UseInterestingIPs)
|
||||
if ifChanged {
|
||||
changed := !curState.EqualFiltered(oldState, interfaces.UseInterestingInterfaces, interfaces.UseInterestingIPs)
|
||||
if changed {
|
||||
m.gwValid = false
|
||||
m.ifState = curState
|
||||
|
||||
@ -322,9 +309,14 @@ func (m *Mon) debounce() {
|
||||
jsonSummary(oldState), jsonSummary(curState))
|
||||
}
|
||||
}
|
||||
changed := ifChanged || timeJumped
|
||||
if changed {
|
||||
m.timeJumped = false
|
||||
// See if we have a queued or new time jump signal.
|
||||
if shouldMonitorTimeJump && m.checkWallTimeAdvanceLocked() {
|
||||
m.resetTimeJumpedLocked()
|
||||
if !changed {
|
||||
// Only log if it wasn't an interesting change.
|
||||
m.logf("time jumped (probably wake from sleep); synthesizing major change event")
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
for _, cb := range m.cbs {
|
||||
go cb(changed, m.ifState)
|
||||
@ -360,22 +352,37 @@ func (m *Mon) pollWallTime() {
|
||||
if m.closed {
|
||||
return
|
||||
}
|
||||
m.checkWallTimeAdvanceLocked()
|
||||
if m.timeJumped {
|
||||
if m.checkWallTimeAdvanceLocked() {
|
||||
m.InjectEvent()
|
||||
}
|
||||
m.wallTimer.Reset(pollWallTimeInterval)
|
||||
}
|
||||
|
||||
// checkWallTimeAdvanceLocked updates m.timeJumped, if wall time jumped
|
||||
// more than 150% of pollWallTimeInterval, indicating we probably just
|
||||
// came out of sleep.
|
||||
func (m *Mon) checkWallTimeAdvanceLocked() {
|
||||
// shouldMonitorTimeJump is whether we keep a regular periodic timer running in
|
||||
// the background watching for jumps in wall time.
|
||||
//
|
||||
// We don't do this on mobile platforms for battery reasons, and because these
|
||||
// platforms don't really sleep in the same way.
|
||||
const shouldMonitorTimeJump = runtime.GOOS != "android" && runtime.GOOS != "ios"
|
||||
|
||||
// checkWallTimeAdvanceLocked reports whether wall time jumped more than 150% of
|
||||
// pollWallTimeInterval, indicating we probably just came out of sleep. Once a
|
||||
// time jump is detected it must be reset by calling resetTimeJumpedLocked.
|
||||
func (m *Mon) checkWallTimeAdvanceLocked() bool {
|
||||
if !shouldMonitorTimeJump {
|
||||
panic("unreachable") // if callers are correct
|
||||
}
|
||||
now := wallTime()
|
||||
if now.Sub(m.lastWall) > pollWallTimeInterval*3/2 {
|
||||
m.timeJumped = true
|
||||
m.timeJumped = true // it is reset by debounce.
|
||||
}
|
||||
m.lastWall = now
|
||||
return m.timeJumped
|
||||
}
|
||||
|
||||
// resetTimeJumpedLocked consumes the signal set by checkWallTimeAdvanceLocked.
|
||||
func (m *Mon) resetTimeJumpedLocked() {
|
||||
m.timeJumped = false
|
||||
}
|
||||
|
||||
type ipRuleDeletedMessage struct {
|
||||
|
Loading…
Reference in New Issue
Block a user