From 70ede2ab323bf7364ae9a76bf4bcabcbb3a5b449 Mon Sep 17 00:00:00 2001 From: Alexandr Stelnykovych Date: Thu, 1 Oct 2020 18:29:13 +0300 Subject: [PATCH] Deadlock fix (#85) Deadlock observed when starting multiple ping routines. It happens when writting to `recv` channel (which is full) and no active readers for this channel. *Example to reproduce the issue* : var waiter sync.WaitGroup pingFunc := func() { defer waiter.Done() pinger, err := ping.NewPinger("8.8.8.8") if err != nil { return } pinger.SetPrivileged(true) pinger.Count = 5 pinger.Interval = time.Second pinger.Timeout = time.Second * 4 pinger.Run() } for i := 0; i < 1000; i++ { waiter.Add(1) go pingFunc() } waiter.Wait() // deadlock here! (reproducible almost every time) --- ping.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ping.go b/ping.go index f226933..9d5f106 100644 --- a/ping.go +++ b/ping.go @@ -471,7 +471,11 @@ func (p *Pinger) recvICMP( } } - recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl} + select { + case <-p.done: + return + case recv <- &packet{bytes: bytes, nbytes: n, ttl: ttl}: + } } } }