🎏Fix a bug where invokers get stuck in waiting idle workers

This commit is contained in:
Andy Pan 2019-08-18 04:15:21 +08:00
parent af70ed0660
commit 08d01b6b48
2 changed files with 16 additions and 14 deletions

15
pool.go
View File

@ -88,13 +88,6 @@ func (p *Pool) periodicallyPurge() {
} }
p.workers = idleWorkers[:m] 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() p.lock.Unlock()
// Notify obsolete workers to stop. // Notify obsolete workers to stop.
@ -105,6 +98,13 @@ func (p *Pool) periodicallyPurge() {
w.task <- nil w.task <- nil
expiredWorkers[i] = 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: Reentry:
p.cond.Wait() p.cond.Wait()
if p.Running() == 0 { if p.Running() == 0 {
p.lock.Unlock()
spawnWorker() spawnWorker()
return w return w
} }

View File

@ -91,13 +91,6 @@ func (p *PoolWithFunc) periodicallyPurge() {
} }
p.workers = idleWorkers[:m] 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() p.lock.Unlock()
// Notify obsolete workers to stop. // Notify obsolete workers to stop.
@ -108,6 +101,13 @@ func (p *PoolWithFunc) periodicallyPurge() {
w.args <- nil w.args <- nil
expiredWorkers[i] = 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: Reentry:
p.cond.Wait() p.cond.Wait()
if p.Running() == 0 { if p.Running() == 0 {
p.lock.Unlock()
spawnWorker() spawnWorker()
return w return w
} }