Skip to content

Commit 7a8f93e

Browse files
committed
Internal change.
PiperOrigin-RevId: 898158090
1 parent 00a38c0 commit 7a8f93e

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

pkg/sync/gate_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,27 @@ func testGateConcurrentOnce(t *testing.T, d time.Duration) {
103103
time.Sleep(d / 2)
104104
}
105105

106+
func TestGateRaceReproduction(t *testing.T) {
107+
var g Gate
108+
var v int32
109+
if !g.Enter() {
110+
t.Fatalf("Enter failed")
111+
}
112+
done := make(chan bool)
113+
go func() {
114+
g.Close()
115+
v = 2 // Used to trigger a write/write race.
116+
done <- true
117+
}()
118+
time.Sleep(50 * time.Millisecond)
119+
v = 1
120+
g.Leave()
121+
<-done
122+
if v != 2 {
123+
t.Errorf("Unexpected value of v: %d", v)
124+
}
125+
}
126+
106127
func BenchmarkGateEnterLeave(b *testing.B) {
107128
var g Gate
108129
for i := 0; i < b.N; i++ {

pkg/sync/gate_unsafe.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ func (g *Gate) leaveClosed() {
110110
if atomic.LoadUintptr(&g.closingG) == 0 {
111111
return
112112
}
113-
if g := atomic.SwapUintptr(&g.closingG, 0); g > preparingG {
114-
goready(g, 0)
113+
if cG := atomic.SwapUintptr(&g.closingG, 0); cG > preparingG {
114+
goready(cG, 0)
115115
}
116116
}
117117

@@ -133,15 +133,16 @@ func (g *Gate) Close() {
133133
panic("concurrent Close of sync.Gate")
134134
}
135135

136-
if g := atomic.SwapUintptr(&g.closingG, preparingG); g != 0 {
137-
panic(fmt.Sprintf("invalid sync.Gate.closingG during Close: %#x", g))
136+
if cG := atomic.SwapUintptr(&g.closingG, preparingG); cG != 0 {
137+
panic(fmt.Sprintf("invalid sync.Gate.closingG during Close: %#x", cG))
138138
}
139139
if atomic.LoadInt32(&g.userCount) == math.MinInt32 {
140140
// The last call to Leave arrived while we were setting up closingG.
141141
return
142142
}
143143
// WaitReasonSemacquire/TraceBlockSync are consistent with WaitGroup.
144144
gopark(gateCommit, gohacks.Noescape(unsafe.Pointer(&g.closingG)), WaitReasonSemacquire, TraceBlockSync, 0)
145+
RaceAcquire(unsafe.Pointer(&g.closingG))
145146
}
146147

147148
//go:norace

0 commit comments

Comments
 (0)