From 4a11a4c546561d5189c6777f3512ccf5a4bea873 Mon Sep 17 00:00:00 2001 From: Milos Gajdos Date: Tue, 3 Dec 2019 15:22:54 +0000 Subject: [PATCH] Fix router race condition --- router/default.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/router/default.go b/router/default.go index f938d1d5..e4305436 100644 --- a/router/default.go +++ b/router/default.go @@ -513,25 +513,28 @@ func (r *router) advertiseEvents() error { // close closes exit channels func (r *router) close() { - // notify all goroutines to finish - close(r.exit) - + log.Debugf("Router closing remaining channels") // drain the advertise channel only if advertising if r.status.Code == Advertising { // drain the event channel for range r.eventChan { } - r.sub.RLock() // close advert subscribers for id, sub := range r.subscribers { + select { + case <-sub: + default: + } + // close the channel close(sub) // delete the subscriber + r.sub.Lock() delete(r.subscribers, id) + r.sub.Unlock() } - r.sub.RUnlock() } // mark the router as Stopped and set its Error to nil @@ -552,6 +555,9 @@ func (r *router) watchErrors() { defer r.Unlock() // if the router is not stopped, stop it if r.status.Code != Stopped { + // notify all goroutines to finish + close(r.exit) + // close all the channels r.close() // set the status error @@ -857,6 +863,9 @@ func (r *router) Stop() error { r.Unlock() return r.status.Error case Running, Advertising: + // notify all goroutines to finish + close(r.exit) + // close all the channels // NOTE: close marks the router status as Stopped r.close()