mirror of
https://github.com/golang/go.git
synced 2025-10-19 11:03:18 +00:00
runtime: establish happens-before between goroutine and bubble exit
synctest.Run waits for all bubbled goroutines to exit before returning. Establish a happens-before relationship between the bubbled goroutines exiting and Run returning. For #67434 Change-Id: Ibda7ec2075ae50838c0851e60dc5b3c6f3ca70fb Reviewed-on: https://go-review.googlesource.com/c/go/+/647755 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
a704d39b29
commit
3924fe92b6
2 changed files with 33 additions and 0 deletions
|
@ -433,6 +433,32 @@ func TestWaitGroup(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestHappensBefore(t *testing.T) {
|
||||
var v int
|
||||
synctest.Run(func() {
|
||||
go func() {
|
||||
v++ // 1
|
||||
}()
|
||||
// Wait creates a happens-before relationship on the above goroutine exiting.
|
||||
synctest.Wait()
|
||||
go func() {
|
||||
v++ // 2
|
||||
}()
|
||||
})
|
||||
// Run exiting creates a happens-before relationship on goroutines started in the bubble.
|
||||
synctest.Run(func() {
|
||||
v++ // 3
|
||||
// There is a happens-before relationship between the time.AfterFunc call,
|
||||
// and the func running.
|
||||
time.AfterFunc(0, func() {
|
||||
v++ // 4
|
||||
})
|
||||
})
|
||||
if got, want := v, 4; got != want {
|
||||
t.Errorf("v = %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func wantPanic(t *testing.T, want string) {
|
||||
if e := recover(); e != nil {
|
||||
if got := fmt.Sprint(e); got != want {
|
||||
|
|
|
@ -182,6 +182,8 @@ func synctestRun(f func()) {
|
|||
sg.active++
|
||||
for {
|
||||
if raceenabled {
|
||||
// Establish a happens-before relationship between a timer being created,
|
||||
// and the timer running.
|
||||
raceacquireg(gp, gp.syncGroup.raceaddr())
|
||||
}
|
||||
unlock(&sg.mu)
|
||||
|
@ -205,6 +207,11 @@ func synctestRun(f func()) {
|
|||
|
||||
total := sg.total
|
||||
unlock(&sg.mu)
|
||||
if raceenabled {
|
||||
// Establish a happens-before relationship between bubbled goroutines exiting
|
||||
// and Run returning.
|
||||
raceacquireg(gp, gp.syncGroup.raceaddr())
|
||||
}
|
||||
if total != 1 {
|
||||
panic("deadlock: all goroutines in bubble are blocked")
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue