From cb99e97f5f12c51a9ab03ada1a2d783eb14b49f7 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 3 Jun 2020 17:28:31 +0200 Subject: [PATCH] Introduce network.isClosed --- user.go | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/user.go b/user.go index a58fecd..ca9d801 100644 --- a/user.go +++ b/user.go @@ -88,14 +88,20 @@ func (net *network) forEachDownstream(f func(*downstreamConn)) { }) } +func (net *network) isStopped() bool { + select { + case <-net.stopped: + return true + default: + return false + } +} + func (net *network) run() { var lastTry time.Time for { - select { - case <-net.stopped: + if net.isStopped() { return - default: - // This space is intentionally left blank } if dur := time.Now().Sub(lastTry); dur < retryConnectMinDelay { @@ -120,6 +126,9 @@ func (net *network) run() { continue } + // TODO: this is racy with net.stopped. If the network is stopped + // before the user goroutine receives eventUpstreamConnected, the + // connection won't be closed. net.user.events <- eventUpstreamConnected{uc} if err := uc.readMessages(net.user.events); err != nil { uc.logger.Printf("failed to handle messages: %v", err) @@ -131,10 +140,7 @@ func (net *network) run() { } func (net *network) stop() { - select { - case <-net.stopped: - return - default: + if !net.isStopped() { close(net.stopped) }