From 0e7173b4473fa954a24ffa7064891451351e0021 Mon Sep 17 00:00:00 2001 From: lzhfromustc <43191155+lzhfromustc@users.noreply.github.com> Date: Mon, 29 Jul 2019 18:23:09 -0700 Subject: [PATCH] pkg/types: Avoid potential double lock of tsafeSet. (tsafeSet).Sub and (tsafeSet).Equals can cause double lock bug if ts and other is pointing the same variable gofmt the code and add some comments --- pkg/types/set.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pkg/types/set.go b/pkg/types/set.go index c111b0c0c0b..e7a3cdc9ab6 100644 --- a/pkg/types/set.go +++ b/pkg/types/set.go @@ -148,6 +148,14 @@ func (ts *tsafeSet) Contains(value string) (exists bool) { func (ts *tsafeSet) Equals(other Set) bool { ts.m.RLock() defer ts.m.RUnlock() + + // If ts and other represent the same variable, avoid calling + // ts.us.Equals(other), to avoid double RLock bug + if _other, ok := other.(*tsafeSet); ok { + if _other == ts { + return true + } + } return ts.us.Equals(other) } @@ -173,6 +181,15 @@ func (ts *tsafeSet) Copy() Set { func (ts *tsafeSet) Sub(other Set) Set { ts.m.RLock() defer ts.m.RUnlock() + + // If ts and other represent the same variable, avoid calling + // ts.us.Sub(other), to avoid double RLock bug + if _other, ok := other.(*tsafeSet); ok { + if _other == ts { + usResult := NewUnsafeSet() + return &tsafeSet{usResult, sync.RWMutex{}} + } + } usResult := ts.us.Sub(other).(*unsafeSet) return &tsafeSet{usResult, sync.RWMutex{}} }