From 3002c87a492c3b7abd995a69497281a02d2d43c5 Mon Sep 17 00:00:00 2001 From: Qian Wang Date: Tue, 6 Aug 2019 21:04:08 +0100 Subject: [PATCH] Fix a server crashing null pointer --- internal/multiplex/switchboard.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal/multiplex/switchboard.go b/internal/multiplex/switchboard.go index f650ca2..c4bb416 100644 --- a/internal/multiplex/switchboard.go +++ b/internal/multiplex/switchboard.go @@ -72,10 +72,10 @@ func (sb *switchboard) send(data []byte, connId *uint32) (int, error) { // in particular if newConnId is removed between the RUnlock and RLock, conns[newConnId] will return // a nil pointer. To prevent this we must get newConnId and the reference to conn itself in one single mutex // protection - if atomic.LoadUint32(&sb.broken) == 1 { + sb.connsM.RLock() + if atomic.LoadUint32(&sb.broken) == 1 || len(sb.conns) == 0 { return 0, errBrokenSwitchboard } - sb.connsM.RLock() newConnId := rand.Intn(len(sb.conns)) conn = sb.conns[uint32(newConnId)] sb.connsM.RUnlock() @@ -85,10 +85,10 @@ func (sb *switchboard) send(data []byte, connId *uint32) (int, error) { } func (sb *switchboard) assignRandomConn() (uint32, error) { - if atomic.LoadUint32(&sb.broken) == 1 { + sb.connsM.RLock() + if atomic.LoadUint32(&sb.broken) == 1 || len(sb.conns) == 0 { return 0, errBrokenSwitchboard } - sb.connsM.RLock() connId := rand.Intn(len(sb.conns)) sb.connsM.RUnlock() return uint32(connId), nil