Skip to content

Commit a029cb7

Browse files
committed
fix: unlock l.mu before calling OnPotentialDeadlock callback
OnPotentialDeadlock is called while l.mu is held. If the callback panics (e.g. to allow the goroutine to unwind while keeping other goroutines running), l.mu remains locked, deadlocking all future lock operations. Unlock l.mu before calling the callback in both the recursive lock and order violation detection paths. For the order violation path, re-acquire l.mu afterward if the callback returns normally. Fixes #29
1 parent c1cf6f8 commit a029cb7

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

deadlock.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,9 @@ func (l *lockOrder) preLock(stack []uintptr, p interface{}) {
427427
buf.Flush()
428428
}
429429
Opts.mu.Unlock()
430+
l.mu.Unlock()
430431
Opts.OnPotentialDeadlock()
431-
break
432+
return
432433
}
433434
}
434435
continue
@@ -454,7 +455,9 @@ func (l *lockOrder) preLock(stack []uintptr, p interface{}) {
454455
buf.Flush()
455456
}
456457
Opts.mu.Unlock()
458+
l.mu.Unlock()
457459
Opts.OnPotentialDeadlock()
460+
l.mu.Lock()
458461
}
459462
// Copy both stacks: they're backed by pooled buffers that will be
460463
// recycled in postUnlock, but l.order entries persist until MaxMapSize.

0 commit comments

Comments
 (0)