From 08d01b6b480f74dfa5586a8901878cd466b66de8 Mon Sep 17 00:00:00 2001 From: Andy Pan Date: Sun, 18 Aug 2019 04:15:21 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=8FFix=20a=20bug=20where=20invokers=20?= =?UTF-8?q?get=20stuck=20in=20waiting=20idle=20workers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pool.go | 15 ++++++++------- pool_func.go | 15 ++++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pool.go b/pool.go index cfd3a20..ef8e977 100644 --- a/pool.go +++ b/pool.go @@ -88,13 +88,6 @@ func (p *Pool) periodicallyPurge() { } p.workers = idleWorkers[:m] } - - // There might be a situation that all workers have been cleaned up - // while some invokers still get stuck in "p.cond.Wait()", - // then it ought to wakes all those invokers. - if len(p.workers) == 0 { - p.cond.Broadcast() - } p.lock.Unlock() // Notify obsolete workers to stop. @@ -105,6 +98,13 @@ func (p *Pool) periodicallyPurge() { w.task <- nil expiredWorkers[i] = nil } + + // There might be a situation that all workers have been cleaned up(no any worker is running) + // while some invokers still get stuck in "p.cond.Wait()", + // then it ought to wakes all those invokers. + if p.Running() == 0 { + p.cond.Broadcast() + } } } @@ -240,6 +240,7 @@ func (p *Pool) retrieveWorker() *Worker { Reentry: p.cond.Wait() if p.Running() == 0 { + p.lock.Unlock() spawnWorker() return w } diff --git a/pool_func.go b/pool_func.go index fd2e225..3f7e202 100644 --- a/pool_func.go +++ b/pool_func.go @@ -91,13 +91,6 @@ func (p *PoolWithFunc) periodicallyPurge() { } p.workers = idleWorkers[:m] } - - // There might be a situation that all workers have been cleaned up - // while some invokers still get stuck in "p.cond.Wait()", - // then it ought to wakes all those invokers. - if len(p.workers) == 0 { - p.cond.Broadcast() - } p.lock.Unlock() // Notify obsolete workers to stop. @@ -108,6 +101,13 @@ func (p *PoolWithFunc) periodicallyPurge() { w.args <- nil expiredWorkers[i] = nil } + + // There might be a situation that all workers have been cleaned up(no any worker is running) + // while some invokers still get stuck in "p.cond.Wait()", + // then it ought to wakes all those invokers. + if p.Running() == 0 { + p.cond.Broadcast() + } } } @@ -245,6 +245,7 @@ func (p *PoolWithFunc) retrieveWorker() *WorkerWithFunc { Reentry: p.cond.Wait() if p.Running() == 0 { + p.lock.Unlock() spawnWorker() return w }