]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix data race in abi finalizer test
authorThan McIntosh <thanm@google.com>
Wed, 14 Apr 2021 19:40:01 +0000 (15:40 -0400)
committerThan McIntosh <thanm@google.com>
Wed, 14 Apr 2021 19:57:35 +0000 (19:57 +0000)
Fix a buglet in TestFinalizerRegisterABI that was causing problems
when run with GOEXPERIMENT=regabi.

Updates #40724.

Change-Id: I950c4aa3df69eada23e600f01e6804eb136ce806
Reviewed-on: https://go-review.googlesource.com/c/go/+/310077
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
src/runtime/abi_test.go

index f50ed879d4646ac821e7a0b24231ff08e0f7c118..b82acfe32594f0497f93a89ddca97d07f64ee7e4 100644 (file)
@@ -17,21 +17,36 @@ import (
        "os/exec"
        "runtime"
        "strings"
+       "sync"
        "testing"
        "time"
 )
 
-var regConfirmRun int
+var regConfirmRunIface int
+var regConfirmRunPtr int
+var regConfirmMU sync.Mutex
+
+func guardedRead(p *int) int {
+       regConfirmMU.Lock()
+       defer regConfirmMU.Unlock()
+       return *p
+}
+
+func guardedWrite(p *int, v int) {
+       regConfirmMU.Lock()
+       defer regConfirmMU.Unlock()
+       *p = v
+}
 
 //go:registerparams
 func regFinalizerPointer(v *Tint) (int, float32, [10]byte) {
-       regConfirmRun = *(*int)(v)
+       guardedWrite(&regConfirmRunPtr, *(*int)(v))
        return 5151, 4.0, [10]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 }
 
 //go:registerparams
 func regFinalizerIface(v Tinter) (int, float32, [10]byte) {
-       regConfirmRun = *(*int)(v.(*Tint))
+       guardedWrite(&regConfirmRunIface, *(*int)(v.(*Tint)))
        return 5151, 4.0, [10]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
 }
 
@@ -81,14 +96,15 @@ func TestFinalizerRegisterABI(t *testing.T) {
                name         string
                fin          interface{}
                confirmValue int
+               confirmRun   *int
        }{
-               {"Pointer", regFinalizerPointer, -1},
-               {"Interface", regFinalizerIface, -2},
+               {"Pointer", regFinalizerPointer, -1, &regConfirmRunPtr},
+               {"Interface", regFinalizerIface, -2, &regConfirmRunIface},
        }
        for i := range tests {
                test := &tests[i]
                t.Run(test.name, func(t *testing.T) {
-                       regConfirmRun = 0
+                       guardedWrite(test.confirmRun, 0)
 
                        x := new(Tint)
                        *x = (Tint)(test.confirmValue)
@@ -102,14 +118,15 @@ func TestFinalizerRegisterABI(t *testing.T) {
 
                        for i := 0; i < 100; i++ {
                                time.Sleep(10 * time.Millisecond)
-                               if regConfirmRun != 0 {
+                               if guardedRead(test.confirmRun) != 0 {
                                        break
                                }
                        }
-                       if regConfirmRun == 0 {
+                       v := guardedRead(test.confirmRun)
+                       if v == 0 {
                                t.Fatal("finalizer failed to execute")
-                       } else if regConfirmRun != test.confirmValue {
-                               t.Fatalf("wrong finalizer executed? regConfirmRun = %d", regConfirmRun)
+                       } else if v != test.confirmValue {
+                               t.Fatalf("wrong finalizer executed? regConfirmRun = %d", v)
                        }
                })
        }