From 3a23fdaf6438608bfae327723e1d2ecc1f2af3cb Mon Sep 17 00:00:00 2001 From: Josh Rickmar Date: Tue, 18 Feb 2014 21:11:33 -0500 Subject: [PATCH] Move duplicater chan send out of default case. At any instant when a duplicated notification must be sent, either one of two channel sends/recvs must occur. The first possibility is that the client is disconnected, in which case the disconnected channel will be read, and then the context removed from the goroutine-managed map. The second possibility is that the disconnect channel has not yet been closed, in which case it must block on an actual message send. This change moves the second case out of the default case of the select statement to avoid a race where: 1) The client has not yet disconnected, and the disconnected chan is not ready for reads. 2) Control switches to the default case. 3) The client disconnects, the goroutine reading the send channel returns, closes the disconnected channel, and no more reads occur. 4) The notification duplicator blocks forever trying to send the message even when the disconnected notification channel has already been closed. --- sockets.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sockets.go b/sockets.go index fb66539..3c61b1d 100644 --- a/sockets.go +++ b/sockets.go @@ -279,8 +279,7 @@ func clientResponseDuplicator() { select { case <-cc.disconnected: delete(clients, cc) - default: - cc.send <- n + case cc.send <- n: } } }