diff options
author | Ian Lance Taylor <iant@golang.org> | 2020-02-25 20:23:15 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2020-02-27 02:37:10 +0000 |
commit | 98858c438016bbafd161b502a148558987aa44d5 (patch) | |
tree | 978a84f4609297e98116e60a9b09d20342f9c27d /src/time/time_test.go | |
parent | af1f3b008281c61c54a5d203ffb69334b7af007c (diff) | |
download | go-98858c438016bbafd161b502a148558987aa44d5.tar.gz go-98858c438016bbafd161b502a148558987aa44d5.zip |
runtime: don't panic on racy use of timers
If we see a racy use of timers, as in concurrent calls to Timer.Reset,
do the operations in an unpredictable order, rather than crashing.
Fixes #37400
Change-Id: Idbac295df2dfd551b6d762909d5040fc532c1b34
Reviewed-on: https://go-review.googlesource.com/c/go/+/221077
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Diffstat (limited to 'src/time/time_test.go')
-rw-r--r-- | src/time/time_test.go | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/src/time/time_test.go b/src/time/time_test.go index 95998c362f..2fc23c4fee 100644 --- a/src/time/time_test.go +++ b/src/time/time_test.go @@ -9,7 +9,6 @@ import ( "encoding/gob" "encoding/json" "fmt" - "internal/race" "math/big" "math/rand" "os" @@ -1393,36 +1392,45 @@ func TestReadFileLimit(t *testing.T) { } // Issue 25686: hard crash on concurrent timer access. +// Issue 37400: panic with "racy use of timers" // This test deliberately invokes a race condition. -// We are testing that we don't crash with "fatal error: panic holding locks". +// We are testing that we don't crash with "fatal error: panic holding locks", +// and that we also don't panic. func TestConcurrentTimerReset(t *testing.T) { - if race.Enabled { - t.Skip("skipping test under race detector") - } - - // We expect this code to panic rather than crash. - // Don't worry if it doesn't panic. - catch := func(i int) { - if e := recover(); e != nil { - t.Logf("panic in goroutine %d, as expected, with %q", i, e) - } else { - t.Logf("no panic in goroutine %d", i) - } + const goroutines = 8 + const tries = 1000 + var wg sync.WaitGroup + wg.Add(goroutines) + timer := NewTimer(Hour) + for i := 0; i < goroutines; i++ { + go func(i int) { + defer wg.Done() + for j := 0; j < tries; j++ { + timer.Reset(Hour + Duration(i*j)) + } + }(i) } + wg.Wait() +} +// Issue 37400: panic with "racy use of timers". +func TestConcurrentTimerResetStop(t *testing.T) { const goroutines = 8 const tries = 1000 var wg sync.WaitGroup - wg.Add(goroutines) + wg.Add(goroutines * 2) timer := NewTimer(Hour) for i := 0; i < goroutines; i++ { go func(i int) { defer wg.Done() - defer catch(i) for j := 0; j < tries; j++ { timer.Reset(Hour + Duration(i*j)) } }(i) + go func(i int) { + defer wg.Done() + timer.Stop() + }(i) } wg.Wait() } |