From 20d83e405f71806b2bf4c7150eb3a6d4cfba9b42 Mon Sep 17 00:00:00 2001 From: yura Date: Fri, 5 Oct 2018 12:47:00 +0300 Subject: [PATCH] clientv3: concurrency.Mutex.Lock() - preserve invariant Convenient invariant: - if werr == nil then lock is supposed to be locked at the moment. While we could not be confident in stronger invariant ('is exactly locked'), it were inconvenient that previous code could return `werr == nil` after Mutex.Unlock. It could happen when ctx is canceled/timeouted exactly after waitDeletes successfully returned werr == nil and before `<-ctx.Done()` checked. While such situation is very rare, it is still possible. fixes #10111 --- clientv3/concurrency/mutex.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/clientv3/concurrency/mutex.go b/clientv3/concurrency/mutex.go index dac9ba5a2a3..77b3582cde5 100644 --- a/clientv3/concurrency/mutex.go +++ b/clientv3/concurrency/mutex.go @@ -68,11 +68,10 @@ func (m *Mutex) Lock(ctx context.Context) error { // wait for deletion revisions prior to myKey hdr, werr := waitDeletes(ctx, client, m.pfx, m.myRev-1) - // release lock key if cancelled - select { - case <-ctx.Done(): + // release lock key if wait failed + if werr != nil { m.Unlock(client.Ctx()) - default: + } else { m.hdr = hdr } return werr