File tree 1 file changed +23
-6
lines changed
1 file changed +23
-6
lines changed Original file line number Diff line number Diff line change @@ -15,9 +15,11 @@ import (
15
15
16
16
// Mutex is etcdv3 lock
17
17
type Mutex struct {
18
- timeout time.Duration
19
- mutex * concurrency.Mutex
20
- session * concurrency.Session
18
+ timeout time.Duration
19
+ mutex * concurrency.Mutex
20
+ session * concurrency.Session
21
+ locked bool
22
+ lockedMux sync.Mutex
21
23
}
22
24
23
25
type lockContext struct {
@@ -73,6 +75,10 @@ func (m *Mutex) Lock(ctx context.Context) (context.Context, error) {
73
75
ctx , cancel = context .WithCancel (ctx )
74
76
rCtx := & lockContext {Context : ctx }
75
77
78
+ m .lockedMux .Lock ()
79
+ m .locked = true
80
+ m .lockedMux .Unlock ()
81
+
76
82
go func () {
77
83
defer cancel ()
78
84
@@ -99,13 +105,20 @@ func (m *Mutex) TryLock(ctx context.Context) (context.Context, error) {
99
105
ctx , cancel = context .WithCancel (ctx )
100
106
rCtx := & lockContext {Context : ctx }
101
107
102
- go func () {
103
- defer cancel ()
108
+ m .lockedMux .Lock ()
109
+ m .locked = true
110
+ m .lockedMux .Unlock ()
104
111
112
+ go func () {
105
113
select {
106
114
case <- m .session .Done ():
107
- rCtx .setError (types .ErrLockSessionDone )
115
+ // session.Done() has multi semantics
116
+ if m .locked {
117
+ rCtx .setError (types .ErrLockSessionDone )
118
+ cancel ()
119
+ }
108
120
case <- ctx .Done ():
121
+ cancel ()
109
122
}
110
123
}()
111
124
@@ -123,6 +136,10 @@ func (m *Mutex) Unlock(ctx context.Context) error {
123
136
}
124
137
125
138
func (m * Mutex ) unlock (ctx context.Context ) error {
139
+ m .lockedMux .Lock ()
140
+ m .locked = false
141
+ m .lockedMux .Unlock ()
142
+
126
143
_ , err := m .session .Client ().Txn (ctx ).If (m .mutex .IsOwner ()).
127
144
Then (clientv3 .OpDelete (m .mutex .Key ())).Commit ()
128
145
// no way to clear it...
You can’t perform that action at this time.
0 commit comments