Fix an issue that blocks all waiting callers when all workers panic

Fixes #146 #147
This commit is contained in:
Andy Pan 2021-03-28 22:37:56 +08:00
parent 2e763f1216
commit dbcb6a104f
4 changed files with 17 additions and 4 deletions

12
pool.go
View File

@ -243,16 +243,20 @@ func (p *Pool) retrieveWorker() (w *goWorker) {
p.blockingNum++ p.blockingNum++
p.cond.Wait() p.cond.Wait()
p.blockingNum-- p.blockingNum--
if p.Running() == 0 { var nw int
if nw = p.Running(); nw == 0 {
p.lock.Unlock() p.lock.Unlock()
if !p.IsClosed() { if !p.IsClosed() {
spawnWorker() spawnWorker()
} }
return return
} }
if w = p.workers.detach(); w == nil {
w = p.workers.detach() if nw < capacity {
if w == nil { p.lock.Unlock()
spawnWorker()
return
}
goto Reentry goto Reentry
} }

View File

@ -270,6 +270,11 @@ func (p *PoolWithFunc) retrieveWorker() (w *goWorkerWithFunc) {
} }
l := len(p.workers) - 1 l := len(p.workers) - 1
if l < 0 { if l < 0 {
if p.Running() < p.Cap() {
p.lock.Unlock()
spawnWorker()
return
}
goto Reentry goto Reentry
} }
w = p.workers[l] w = p.workers[l]

View File

@ -59,6 +59,8 @@ func (w *goWorker) run() {
w.pool.options.Logger.Printf("worker exits from panic: %s\n", string(buf[:n])) w.pool.options.Logger.Printf("worker exits from panic: %s\n", string(buf[:n]))
} }
} }
// Call Signal() here in case there are goroutines waiting for available workers.
w.pool.cond.Signal()
}() }()
for f := range w.task { for f := range w.task {

View File

@ -59,6 +59,8 @@ func (w *goWorkerWithFunc) run() {
w.pool.options.Logger.Printf("worker with func exits from panic: %s\n", string(buf[:n])) w.pool.options.Logger.Printf("worker with func exits from panic: %s\n", string(buf[:n]))
} }
} }
// Call Signal() here in case there are goroutines waiting for available workers.
w.pool.cond.Signal()
}() }()
for args := range w.args { for args := range w.args {