fix(time): data race in DefaultTimeNow

This commit is contained in:
yusing
2025-11-01 02:18:24 +08:00
parent e8fb202ea9
commit e3915210aa
2 changed files with 11 additions and 7 deletions

View File

@@ -10,7 +10,7 @@ var (
TimeNow = DefaultTimeNow TimeNow = DefaultTimeNow
shouldCallTimeNow atomic.Bool shouldCallTimeNow atomic.Bool
timeNowTicker = time.NewTicker(shouldCallTimeNowInterval) timeNowTicker = time.NewTicker(shouldCallTimeNowInterval)
lastTimeNow = time.Now() lastTimeNow = atomic.NewTime(time.Now())
) )
const shouldCallTimeNowInterval = 100 * time.Millisecond const shouldCallTimeNowInterval = 100 * time.Millisecond
@@ -26,11 +26,13 @@ func MockTimeNow(t time.Time) {
// //
// Returned value may have +-100ms error. // Returned value may have +-100ms error.
func DefaultTimeNow() time.Time { func DefaultTimeNow() time.Time {
if shouldCallTimeNow.Load() { swapped := shouldCallTimeNow.CompareAndSwap(false, true)
lastTimeNow = time.Now() if swapped { // first call
shouldCallTimeNow.Store(false) now := time.Now()
lastTimeNow.Store(now)
return now
} }
return lastTimeNow return lastTimeNow.Load()
} }
func init() { func init() {

View File

@@ -5,16 +5,18 @@ import (
"time" "time"
) )
var sink time.Time
func BenchmarkTimeNow(b *testing.B) { func BenchmarkTimeNow(b *testing.B) {
b.Run("default", func(b *testing.B) { b.Run("default", func(b *testing.B) {
for b.Loop() { for b.Loop() {
time.Now() sink = time.Now()
} }
}) })
b.Run("reduced_call", func(b *testing.B) { b.Run("reduced_call", func(b *testing.B) {
for b.Loop() { for b.Loop() {
DefaultTimeNow() sink = DefaultTimeNow()
} }
}) })
} }