From cd514799dad434a4c8c2154d45efc5aa552c1c6a Mon Sep 17 00:00:00 2001 From: Arceliar Date: Wed, 13 Jun 2018 00:24:12 -0500 Subject: [PATCH] recover if p.doSend is closed due to a race between peers.doSendSwitchMsgs and peers.removePeer --- src/yggdrasil/peer.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/yggdrasil/peer.go b/src/yggdrasil/peer.go index caedeb7..ad99750 100644 --- a/src/yggdrasil/peer.go +++ b/src/yggdrasil/peer.go @@ -166,17 +166,24 @@ func (ps *peers) sendSwitchMsgs() { if p.port == 0 { continue } - select { - case p.doSend <- struct{}{}: - default: - } + p.doSendSwitchMsgs() + } +} + +// If called, sends a notification to the peer's linkLoop to trigger a switchMsg send. +// Mainly called by sendSwitchMsgs or during linkLoop startup. +func (p *peer) doSendSwitchMsgs() { + defer func() { recover() }() // In case there's a race with close(p.doSend) + select { + case p.doSend <- struct{}{}: + default: } } // This must be launched in a separate goroutine by whatever sets up the peer struct. // It handles link protocol traffic. func (p *peer) linkLoop() { - go func() { p.doSend <- struct{}{} }() + go p.doSendSwitchMsgs() tick := time.NewTicker(time.Second) defer tick.Stop() for {