ソースを参照

grpcproxy: fix race between watch ranges delete() and broadcasts empty()

Checking empty() wasn't grabbing the broadcasts lock so the race detector
flags it as a data race with coalesce(). Instead, just return the number
of remaining watches following delete() and get rid of empty().
Anthony Romano 9 年 前
コミット
d680b8b5fb
2 ファイル変更4 行追加5 行削除
  1. 3 3
      proxy/grpcproxy/watch_broadcasts.go
  2. 1 2
      proxy/grpcproxy/watch_ranges.go

+ 3 - 3
proxy/grpcproxy/watch_broadcasts.go

@@ -96,7 +96,8 @@ func (wbs *watchBroadcasts) add(w *watcher) {
 	wbs.bcasts[wb] = struct{}{}
 	wbs.bcasts[wb] = struct{}{}
 }
 }
 
 
-func (wbs *watchBroadcasts) delete(w *watcher) {
+// delete removes a watcher and returns the number of remaining watchers.
+func (wbs *watchBroadcasts) delete(w *watcher) int {
 	wbs.mu.Lock()
 	wbs.mu.Lock()
 	defer wbs.mu.Unlock()
 	defer wbs.mu.Unlock()
 
 
@@ -110,10 +111,9 @@ func (wbs *watchBroadcasts) delete(w *watcher) {
 		delete(wbs.bcasts, wb)
 		delete(wbs.bcasts, wb)
 		wb.stop()
 		wb.stop()
 	}
 	}
+	return len(wbs.bcasts)
 }
 }
 
 
-func (wbs *watchBroadcasts) empty() bool { return len(wbs.bcasts) == 0 }
-
 func (wbs *watchBroadcasts) stop() {
 func (wbs *watchBroadcasts) stop() {
 	wbs.mu.Lock()
 	wbs.mu.Lock()
 	for wb := range wbs.bcasts {
 	for wb := range wbs.bcasts {

+ 1 - 2
proxy/grpcproxy/watch_ranges.go

@@ -53,8 +53,7 @@ func (wrs *watchRanges) delete(w *watcher) {
 	if !ok {
 	if !ok {
 		panic("deleting missing range")
 		panic("deleting missing range")
 	}
 	}
-	wbs.delete(w)
-	if wbs.empty() {
+	if wbs.delete(w) == 0 {
 		wbs.stop()
 		wbs.stop()
 		delete(wrs.bcasts, w.wr)
 		delete(wrs.bcasts, w.wr)
 	}
 	}