Просмотр исходного кода

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
yura 7 лет назад
Родитель
Сommit
20d83e405f
1 измененных файлов с 3 добавлено и 4 удалено
  1. 3 4
      clientv3/concurrency/mutex.go

+ 3 - 4
clientv3/concurrency/mutex.go

@@ -68,11 +68,10 @@ func (m *Mutex) Lock(ctx context.Context) error {
 
 
 	// wait for deletion revisions prior to myKey
 	// wait for deletion revisions prior to myKey
 	hdr, werr := waitDeletes(ctx, client, m.pfx, m.myRev-1)
 	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())
 		m.Unlock(client.Ctx())
-	default:
+	} else {
 		m.hdr = hdr
 		m.hdr = hdr
 	}
 	}
 	return werr
 	return werr