Fix router race condition

This commit is contained in:
Milos Gajdos 2019-12-03 15:22:54 +00:00
parent bb1a1358b7
commit 4a11a4c546
No known key found for this signature in database
GPG Key ID: 8B31058CC55DFD4F

View File

@ -513,25 +513,28 @@ func (r *router) advertiseEvents() error {
// close closes exit channels // close closes exit channels
func (r *router) close() { func (r *router) close() {
// notify all goroutines to finish log.Debugf("Router closing remaining channels")
close(r.exit)
// drain the advertise channel only if advertising // drain the advertise channel only if advertising
if r.status.Code == Advertising { if r.status.Code == Advertising {
// drain the event channel // drain the event channel
for range r.eventChan { for range r.eventChan {
} }
r.sub.RLock()
// close advert subscribers // close advert subscribers
for id, sub := range r.subscribers { for id, sub := range r.subscribers {
select {
case <-sub:
default:
}
// close the channel // close the channel
close(sub) close(sub)
// delete the subscriber // delete the subscriber
r.sub.Lock()
delete(r.subscribers, id) delete(r.subscribers, id)
r.sub.Unlock()
} }
r.sub.RUnlock()
} }
// mark the router as Stopped and set its Error to nil // mark the router as Stopped and set its Error to nil
@ -552,6 +555,9 @@ func (r *router) watchErrors() {
defer r.Unlock() defer r.Unlock()
// if the router is not stopped, stop it // if the router is not stopped, stop it
if r.status.Code != Stopped { if r.status.Code != Stopped {
// notify all goroutines to finish
close(r.exit)
// close all the channels // close all the channels
r.close() r.close()
// set the status error // set the status error
@ -857,6 +863,9 @@ func (r *router) Stop() error {
r.Unlock() r.Unlock()
return r.status.Error return r.status.Error
case Running, Advertising: case Running, Advertising:
// notify all goroutines to finish
close(r.exit)
// close all the channels // close all the channels
// NOTE: close marks the router status as Stopped // NOTE: close marks the router status as Stopped
r.close() r.close()