From a019fdaec9f04b00c13f1db034509fc69d2a9bae Mon Sep 17 00:00:00 2001 From: Cecylia Bocovich Date: Thu, 24 Oct 2024 11:08:24 -0400 Subject: [PATCH] Perform SnowflakeConn.Close() logic only once Use synchronization to avoid a panic if SnowflakeConn.Close is called more than once. --- client/lib/peers.go | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/client/lib/peers.go b/client/lib/peers.go index 1c39425..e828ce5 100644 --- a/client/lib/peers.go +++ b/client/lib/peers.go @@ -29,6 +29,7 @@ type Peers struct { melt chan struct{} collectLock sync.Mutex + closeOnce sync.Once } // NewPeers constructs a fresh container of remote peers. @@ -122,17 +123,19 @@ func (p *Peers) purgeClosedPeers() { // End closes all active connections to Peers contained here, and stops the // collection of future Peers. func (p *Peers) End() { - close(p.melt) - p.collectLock.Lock() - defer p.collectLock.Unlock() - close(p.snowflakeChan) - cnt := p.Count() - for e := p.activePeers.Front(); e != nil; { - next := e.Next() - conn := e.Value.(*WebRTCPeer) - conn.Close() - p.activePeers.Remove(e) - e = next - } - log.Printf("WebRTC: melted all %d snowflakes.", cnt) + p.closeOnce.Do(func() { + close(p.melt) + p.collectLock.Lock() + defer p.collectLock.Unlock() + close(p.snowflakeChan) + cnt := p.Count() + for e := p.activePeers.Front(); e != nil; { + next := e.Next() + conn := e.Value.(*WebRTCPeer) + conn.Close() + p.activePeers.Remove(e) + e = next + } + log.Printf("WebRTC: melted all %d snowflakes.", cnt) + }) }