Skip to content

Commit 407a57b

Browse files
authored
owner: fix data race on ownerManager.campaignCancel (#56362) (#57130)
close #56053
1 parent 7ee327f commit 407a57b

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

owner/manager.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ func (m *ownerManager) CampaignOwner() error {
154154
return errors.Trace(err)
155155
}
156156
m.wg.Add(1)
157-
go m.campaignLoop(session)
157+
var campaignContext context.Context
158+
campaignContext, m.campaignCancel = context.WithCancel(m.ctx)
159+
go m.campaignLoop(campaignContext, session)
158160
return nil
159161
}
160162

@@ -194,9 +196,7 @@ func (m *ownerManager) CampaignCancel() {
194196
m.wg.Wait()
195197
}
196198

197-
func (m *ownerManager) campaignLoop(etcdSession *concurrency.Session) {
198-
var campaignContext context.Context
199-
campaignContext, m.campaignCancel = context.WithCancel(m.ctx)
199+
func (m *ownerManager) campaignLoop(campaignContext context.Context, etcdSession *concurrency.Session) {
200200
defer func() {
201201
m.campaignCancel()
202202
if r := recover(); r != nil {

owner/manager_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@ import (
3636

3737
const testLease = 5 * time.Millisecond
3838

39+
type testInfo struct {
40+
cluster *integration.ClusterV3
41+
client *clientv3.Client
42+
}
43+
44+
func newTestInfo(t *testing.T) *testInfo {
45+
cluster := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
46+
return &testInfo{
47+
cluster: cluster,
48+
client: cluster.Client(0),
49+
}
50+
}
51+
52+
func (ti *testInfo) Close(t *testing.T) {
53+
ti.cluster.Terminate(t)
54+
}
55+
3956
func TestSingle(t *testing.T) {
4057
if runtime.GOOS == "windows" {
4158
t.Skip("integration.NewClusterV3 will create file contains a colon which is not allowed on Windows")
@@ -340,3 +357,20 @@ func deleteLeader(cli *clientv3.Client, prefixKey string) error {
340357
_, err = cli.Delete(context.Background(), string(resp.Kvs[0].Key))
341358
return errors.Trace(err)
342359
}
360+
361+
func TestImmediatelyCancel(t *testing.T) {
362+
if runtime.GOOS == "windows" {
363+
t.Skip("integration.NewClusterV3 will create file contains a colon which is not allowed on Windows")
364+
}
365+
integration.BeforeTestExternal(t)
366+
367+
tInfo := newTestInfo(t)
368+
defer tInfo.Close(t)
369+
ownerMgr := owner.NewOwnerManager(context.Background(), tInfo.client, "ddl", "1", "/owner/key")
370+
defer ownerMgr.Cancel()
371+
for i := 0; i < 10; i++ {
372+
err := ownerMgr.CampaignOwner()
373+
require.NoError(t, err)
374+
ownerMgr.CampaignCancel()
375+
}
376+
}

0 commit comments

Comments
 (0)