Skip to content

Commit

Permalink
fix: possible deadlocks and panics when calling rueidislock.Close
Browse files Browse the repository at this point in the history
Signed-off-by: Rueian <[email protected]>
  • Loading branch information
rueian committed Aug 9, 2024
1 parent 44224d4 commit 5acf6b9
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions rueidislock/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -352,10 +352,14 @@ func (m *locker) try(ctx context.Context, cancel context.CancelFunc, name string
}
if err != ErrNotLocked {
if err = m.acquire(ctx, key, val, deadline, force); force && err == nil {
select {
case ch <- struct{}{}:
default:
m.mu.RLock()
if m.gates != nil {
select {
case ch <- struct{}{}:
default:
}
}
m.mu.RUnlock()
}
}
go monitoring(err, key, deadline, ch)
Expand Down Expand Up @@ -432,7 +436,7 @@ func (m *locker) WithContext(ctx context.Context, name string) (context.Context,
return ctx, cancel, nil
}
m.mu.Lock()
if g.w--; g.w == 0 && err != nil {
if g.w--; g.w == 0 && err != nil { // delete g from m.gates only when exiting with an error.
if m.gates[name] == g {
delete(m.gates, name)
}
Expand All @@ -450,13 +454,16 @@ func (m *locker) Client() rueidis.Client {
}

func (m *locker) Close() {
m.client.Close() // close the underlying client first so that onInvalidations will not be call anymore.
m.mu.Lock()
for _, g := range m.gates {
for _, ch := range g.csc {
close(ch) // close channels after no more onInvalidations calls.
}
close(g.ch)
}
m.gates = nil
m.mu.Unlock()
m.client.Close()
}

var (
Expand Down

0 comments on commit 5acf6b9

Please sign in to comment.