瀏覽代碼

Fix leak of handleTableEvents

The channel ch.C is never closed.
Added the listen of the ch.Done() to guarantee
that the goroutine is exiting once the event channel
is closed

Signed-off-by: Flavio Crisciani <flavio.crisciani@docker.com>
Flavio Crisciani 8 年之前
父節點
當前提交
6d768ef73c
共有 3 個文件被更改,包括 9 次插入11 次删除
  1. 4 6
      libnetwork/agent.go
  2. 3 3
      libnetwork/networkdb/networkdb_test.go
  3. 2 2
      libnetwork/networkdb/watch.go

+ 4 - 6
libnetwork/agent.go

@@ -722,15 +722,13 @@ func (n *network) cancelDriverWatches() {
 	}
 }
 
-func (c *controller) handleTableEvents(ch chan events.Event, fn func(events.Event)) {
+func (c *controller) handleTableEvents(ch *events.Channel, fn func(events.Event)) {
 	for {
 		select {
-		case ev, ok := <-ch:
-			if !ok {
-				return
-			}
-
+		case ev := <-ch.C:
 			fn(ev)
+		case <-ch.Done():
+			return
 		}
 	}
 }

+ 3 - 3
libnetwork/networkdb/networkdb_test.go

@@ -339,17 +339,17 @@ func TestNetworkDBWatch(t *testing.T) {
 	err = dbs[0].CreateEntry("test_table", "network1", "test_key", []byte("test_value"))
 	assert.NoError(t, err)
 
-	testWatch(t, ch, CreateEvent{}, "test_table", "network1", "test_key", "test_value")
+	testWatch(t, ch.C, CreateEvent{}, "test_table", "network1", "test_key", "test_value")
 
 	err = dbs[0].UpdateEntry("test_table", "network1", "test_key", []byte("test_updated_value"))
 	assert.NoError(t, err)
 
-	testWatch(t, ch, UpdateEvent{}, "test_table", "network1", "test_key", "test_updated_value")
+	testWatch(t, ch.C, UpdateEvent{}, "test_table", "network1", "test_key", "test_updated_value")
 
 	err = dbs[0].DeleteEntry("test_table", "network1", "test_key")
 	assert.NoError(t, err)
 
-	testWatch(t, ch, DeleteEvent{}, "test_table", "network1", "test_key", "")
+	testWatch(t, ch.C, DeleteEvent{}, "test_table", "network1", "test_key", "")
 
 	cancel()
 	closeNetworkDBInstances(dbs)

+ 2 - 2
libnetwork/networkdb/watch.go

@@ -43,7 +43,7 @@ type DeleteEvent event
 // filter is an empty string it acts as a wildcard for that
 // field. Watch returns a channel of events, where the events will be
 // sent.
-func (nDB *NetworkDB) Watch(tname, nid, key string) (chan events.Event, func()) {
+func (nDB *NetworkDB) Watch(tname, nid, key string) (*events.Channel, func()) {
 	var matcher events.Matcher
 
 	if tname != "" || nid != "" || key != "" {
@@ -82,7 +82,7 @@ func (nDB *NetworkDB) Watch(tname, nid, key string) (chan events.Event, func())
 	}
 
 	nDB.broadcaster.Add(sink)
-	return ch.C, func() {
+	return ch, func() {
 		nDB.broadcaster.Remove(sink)
 		ch.Close()
 		sink.Close()