Przeglądaj źródła

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
lzhfromustc 6 lat temu
rodzic
commit
524278c187
1 zmienionych plików z 17 dodań i 0 usunięć
  1. 17 0
      pkg/types/set.go

+ 17 - 0
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{}}
 }