2
0

Fix deadlock race when acquire is cancelled

If the waiter goroutine completes before the section guarding
canceledAcquireCount has run, then there is a deadlock because there is
nothing that can unlock the mutex. Scheduling the second goroutine
ensures that one of the two can release the lock and keep things moving.
This commit is contained in:
Michael Tharp
2019-12-16 21:52:20 +00:00
parent 11cab39313
commit 26cd25c14b
+3 -4
View File
@@ -303,10 +303,6 @@ func (p *Pool) Acquire(ctx context.Context) (*Resource, error) {
select {
case <-ctx.Done():
p.cond.L.Lock()
p.canceledAcquireCount += 1
p.cond.L.Unlock()
// Allow goroutine waiting for signal to exit. Re-signal since we couldn't
// do anything with it. Another goroutine might be waiting.
go func() {
@@ -315,6 +311,9 @@ func (p *Pool) Acquire(ctx context.Context) (*Resource, error) {
p.cond.L.Unlock()
}()
p.cond.L.Lock()
p.canceledAcquireCount += 1
p.cond.L.Unlock()
return nil, ctx.Err()
case <-waitChan:
}