From 6469ce582904e62e0b971c6b79a6c6331c39b224 Mon Sep 17 00:00:00 2001 From: Flavio Crisciani Date: Wed, 31 May 2017 09:49:55 -0700 Subject: [PATCH] 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 --- agent.go | 10 ++++------ networkdb/networkdb_test.go | 6 +++--- networkdb/watch.go | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/agent.go b/agent.go index 76f7ac68d4..58d2b89c35 100644 --- a/agent.go +++ b/agent.go @@ -595,15 +595,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 } } } diff --git a/networkdb/networkdb_test.go b/networkdb/networkdb_test.go index bdcb6c51a5..0929e3c132 100644 --- a/networkdb/networkdb_test.go +++ b/networkdb/networkdb_test.go @@ -332,17 +332,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) diff --git a/networkdb/watch.go b/networkdb/watch.go index 088b666f01..2ef30422a8 100644 --- a/networkdb/watch.go +++ b/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()