Skip to content

Commit dc39be8

Browse files
runtime: use atomic.Cas to change timerRemoved to timerWaiting
If multiple goroutines call time.(*Timer).Reset then the timer will go from timerWaiting to timerDeleted to timerModifying to timerModifiedLater. The timer can be on a different P, meaning that simultaneously cleantimers could change it from timerDeleted to timerRemoving to timerRemoved. If Reset sees timerRemoved, it was doing an atomic.Store of timerWaiting, meaning that it did not necessarily see the other values set in the timer, so the timer could appear to be in an inconsistent state. Use atomic.Cas to avoid that possibility. Updates #6239 Updates #27707 Fixes #35272 Change-Id: I1d59a13dc4f2ff4af110fc6e032c8c9d59cfc270 Reviewed-on: https://go-review.googlesource.com/c/go/+/204717 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Michael Knyszek <[email protected]>
1 parent 130f3c0 commit dc39be8

File tree

1 file changed

+9
-7
lines changed

1 file changed

+9
-7
lines changed

src/runtime/time.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -585,9 +585,10 @@ loop:
585585
case timerNoStatus, timerRemoved:
586586
// Timer was already run and t is no longer in a heap.
587587
// Act like addtimer.
588-
wasRemoved = true
589-
atomic.Store(&t.status, timerWaiting)
590-
break loop
588+
if atomic.Cas(&t.status, status, timerWaiting) {
589+
wasRemoved = true
590+
break loop
591+
}
591592
case timerRunning, timerRemoving, timerMoving:
592593
// The timer is being run or moved, by a different P.
593594
// Wait for it to complete.
@@ -687,10 +688,11 @@ func resettimer(t *timer, when int64) {
687688
for {
688689
switch s := atomic.Load(&t.status); s {
689690
case timerNoStatus, timerRemoved:
690-
atomic.Store(&t.status, timerWaiting)
691-
t.when = when
692-
addInitializedTimer(t)
693-
return
691+
if atomic.Cas(&t.status, s, timerWaiting) {
692+
t.when = when
693+
addInitializedTimer(t)
694+
return
695+
}
694696
case timerDeleted:
695697
if atomic.Cas(&t.status, s, timerModifying) {
696698
t.nextwhen = when

0 commit comments

Comments
 (0)