Skip to content

Commit

Permalink
pkg/types: Avoid potential double lock of tsafeSet.
Browse files Browse the repository at this point in the history
(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
  • Loading branch information
lzhfromustc committed Aug 7, 2019
1 parent 1583547 commit 0e7173b
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions pkg/types/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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{}}
}

0 comments on commit 0e7173b

Please sign in to comment.