Skip to content

Commit 59f65e0

Browse files
tell apart etcd lock session done from normal occasions (#440)
1 parent d33f2fc commit 59f65e0

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

lock/etcdlock/mutex.go

+23-6
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@ import (
1515

1616
// Mutex is etcdv3 lock
1717
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
2123
}
2224

2325
type lockContext struct {
@@ -73,6 +75,10 @@ func (m *Mutex) Lock(ctx context.Context) (context.Context, error) {
7375
ctx, cancel = context.WithCancel(ctx)
7476
rCtx := &lockContext{Context: ctx}
7577

78+
m.lockedMux.Lock()
79+
m.locked = true
80+
m.lockedMux.Unlock()
81+
7682
go func() {
7783
defer cancel()
7884

@@ -99,13 +105,20 @@ func (m *Mutex) TryLock(ctx context.Context) (context.Context, error) {
99105
ctx, cancel = context.WithCancel(ctx)
100106
rCtx := &lockContext{Context: ctx}
101107

102-
go func() {
103-
defer cancel()
108+
m.lockedMux.Lock()
109+
m.locked = true
110+
m.lockedMux.Unlock()
104111

112+
go func() {
105113
select {
106114
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+
}
108120
case <-ctx.Done():
121+
cancel()
109122
}
110123
}()
111124

@@ -123,6 +136,10 @@ func (m *Mutex) Unlock(ctx context.Context) error {
123136
}
124137

125138
func (m *Mutex) unlock(ctx context.Context) error {
139+
m.lockedMux.Lock()
140+
m.locked = false
141+
m.lockedMux.Unlock()
142+
126143
_, err := m.session.Client().Txn(ctx).If(m.mutex.IsOwner()).
127144
Then(clientv3.OpDelete(m.mutex.Key())).Commit()
128145
// no way to clear it...

0 commit comments

Comments
 (0)