You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Remove call to acquire() method from tryAcquire() to prevent deadlock
* Deadlock scenario: tryAcquire() holds s.lock mutex, then calls acquire()
which tries to acquire the same mutex again, causing goroutine to wait
forever
* Implement semaphore acquisition logic directly in tryAcquire() method
* Both methods were attempting to obtain the same non-reentrant mutex
The issue occurred because:
- tryAcquire() already holds s.lock via defer s.lock.Unlock()
- When tryAcquire() called s.acquire(nextKey), acquire() would attempt
s.lock.Lock() again
- Since Go's sync.Mutex is not reentrant, this created a deadlock where
the same goroutine was waiting for a lock it already held
The fix:
- Replace s.acquire(nextKey) call with direct s.semaphore.TryAcquire(1)
- Manage s.running[key] = true assignment directly within tryAcquire()
- Maintain acquire() method with proper locking for other callers
- Add comprehensive test coverage for deadlock scenarios
Tests added:
- TestTryAcquireDeadlockTimeout: Detects hanging behavior with timeout
- TestTryAcquireDeadlockScenario: Tests concurrent access patterns
- TestTryAcquireConcurrentAccess: Validates proper concurrent behavior
The acquire() method retains its mutex protection as it may be called
independently by other parts of the codebase outside the context of
tryAcquire().
Signed-off-by: Chmouel Boudjnah <[email protected]>
Co-authored-by: Cursor (claude-4)
Signed-off-by: Chmouel Boudjnah <[email protected]>
0 commit comments