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.
This commit is contained in:
Josh Rickmar 2014-02-18 21:11:33 -05:00
parent 2ff7f85b0c
commit 3a23fdaf64

View file

@ -279,8 +279,7 @@ func clientResponseDuplicator() {
select { select {
case <-cc.disconnected: case <-cc.disconnected:
delete(clients, cc) delete(clients, cc)
default: case cc.send <- n:
cc.send <- n
} }
} }
} }