mirror of
https://github.com/golang/go.git
synced 2026-06-27 19:30:52 +00:00
runtime: avoid concurrent use of synctest timer race context.
When running a timer in a synctest bubble, create a temporary race context for the operation. We can't use the bubble timer's context, because multiple timers can execute simultaneously within a bubble. Fixes #76691 Change-Id: If862dd63333c5b3b2e75d44a078acd0e9da77a8f Reviewed-on: https://go-review.googlesource.com/c/go/+/753200 Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> Commit-Queue: Damien Neil <dneil@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com>
This commit is contained in:
parent
15b9fc2659
commit
784ea961a4
2 changed files with 17 additions and 12 deletions
|
|
@ -1126,13 +1126,7 @@ func (t *timer) unlockAndRun(now int64, bubble *synctestBubble) {
|
|||
// Note that we are running on a system stack,
|
||||
// so there is no chance of getg().m being reassigned
|
||||
// out from under us while this function executes.
|
||||
gp := getg()
|
||||
var tsLocal *timers
|
||||
if bubble == nil {
|
||||
tsLocal = &gp.m.p.ptr().timers
|
||||
} else {
|
||||
tsLocal = &bubble.timers
|
||||
}
|
||||
tsLocal := &getg().m.p.ptr().timers
|
||||
if tsLocal.raceCtx == 0 {
|
||||
tsLocal.raceCtx = racegostart(abi.FuncPCABIInternal((*timers).run) + sys.PCQuantum)
|
||||
}
|
||||
|
|
@ -1184,11 +1178,7 @@ func (t *timer) unlockAndRun(now int64, bubble *synctestBubble) {
|
|||
if gp.racectx != 0 {
|
||||
throw("unexpected racectx")
|
||||
}
|
||||
if bubble == nil {
|
||||
gp.racectx = gp.m.p.ptr().timers.raceCtx
|
||||
} else {
|
||||
gp.racectx = bubble.timers.raceCtx
|
||||
}
|
||||
gp.racectx = gp.m.p.ptr().timers.raceCtx
|
||||
}
|
||||
|
||||
if ts != nil {
|
||||
|
|
|
|||
|
|
@ -188,3 +188,18 @@ func TestNow(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestSynctestTimerRaceCtxCrash(t *testing.T) {
|
||||
for range 20 {
|
||||
t.Run("", func(t *testing.T) {
|
||||
synctest.Test(t, func(t *testing.T) {
|
||||
for range 100 {
|
||||
time.AfterFunc(1*time.Second, func() {
|
||||
time.AfterFunc(0, func() {})
|
||||
})
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue