From 8bacc6cdd991cc932671307e8b6dad4a83c9678f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 19 Feb 2019 18:10:01 +0000 Subject: [PATCH 1/2] dialqueue: fix possible worker goroutine leak. --- dial_queue.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dial_queue.go b/dial_queue.go index 62fbf03e507..0315bb15f33 100644 --- a/dial_queue.go +++ b/dial_queue.go @@ -323,7 +323,14 @@ func (dq *dialQueue) worker() { } logger.Debugf("dialling %v took %dms (as observed by the dht subsystem).", p, time.Since(t)/time.Millisecond) waiting := len(dq.waitingCh) - dq.out.EnqChan <- p + + // by the time we're done dialling, it's possible that the context is closed, in which case there will + // be nobody listening on dq.out.EnqChan and we could block forever. + select { + case dq.out.EnqChan <- p: + case <-dq.ctx.Done(): + return + } if waiting > 0 { // we have somebody to deliver this value to, so no need to shrink. continue From 4f0cf486fa2a8ccbce14dd047c1a18c0f50d7f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Tue, 19 Feb 2019 18:10:56 +0000 Subject: [PATCH 2/2] dialqueue: rename local var for clarity. --- dial_queue.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dial_queue.go b/dial_queue.go index 0315bb15f33..75cc703f64c 100644 --- a/dial_queue.go +++ b/dial_queue.go @@ -110,7 +110,7 @@ type waitingCh struct { // end up adding fuel to the fire. Since we have no deterministic way to detect this for now, we hard-limit concurrency // to config.maxParallelism. func newDialQueue(params *dqParams) (*dialQueue, error) { - sq := &dialQueue{ + dq := &dialQueue{ dqParams: params, nWorkers: params.config.minParallelism, out: queue.NewChanQueue(params.ctx, queue.NewXORDistancePQ(params.target)), @@ -121,10 +121,10 @@ func newDialQueue(params *dqParams) (*dialQueue, error) { } for i := 0; i < int(params.config.minParallelism); i++ { - go sq.worker() + go dq.worker() } - go sq.control() - return sq, nil + go dq.control() + return dq, nil } func (dq *dialQueue) control() {