fix #2376 - avoid deadlock scenario when completing dead connections by mgravell · Pull Request #2378 · StackExchange/StackExchange.Redis (original) (raw)

Deadlock scenario reported with one path (RecordConnectionFailed) taking queue then message locks, and another path (ExecuteSyncImpl) taking message then queue locks; change both paths to only take one lock at a time - never nested.

  1. in RecordConnectionFailed don't hold the queue lock when we abort things - only hold it when fetching next
  2. in ExecuteSyncImpl, don't hold the message lock when throwing for timeout
  3. to avoid similar not yet seen: in GetHeadMessages, don't blindly wait forever on the message lock

also standardise on TryPeek/TryDequeue