diff --git a/src/runtime/time_go122.go b/src/runtime/time_go122.go index 2693555cf5..57481a6e71 100644 --- a/src/runtime/time_go122.go +++ b/src/runtime/time_go122.go @@ -53,6 +53,11 @@ func startTimer(tim *timer) { //go:linkname stopTimer time.stopTimer func stopTimer(tim *timer) bool { + // Set period to 0 to prevent the timer from being re-added to the queue + // if the callback is currently running. This must be done before removing + // the timer to avoid a race condition where the callback re-adds the timer + // after it's been removed. + tim.period = 0 return removeTimer(tim) != nil } diff --git a/src/runtime/time_go123.go b/src/runtime/time_go123.go index e39da74488..9ea36e6487 100644 --- a/src/runtime/time_go123.go +++ b/src/runtime/time_go123.go @@ -52,6 +52,11 @@ func newTimer(when, period int64, f func(arg any, seq uintptr, delta int64), arg //go:linkname stopTimer time.stopTimer func stopTimer(tim *timeTimer) bool { + // Set period to 0 to prevent the timer from being re-added to the queue + // if the callback is currently running. This must be done before removing + // the timer to avoid a race condition where the callback re-adds the timer + // after it's been removed. + tim.timer.period = 0 return removeTimer(&tim.timer) != nil }