Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-96150

SemaphoreTIcketHolder can leave waiters blocked even when tickets are available

    • Type: Icon: Bug Bug
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Workload Scheduling
    • ALL

      Consider a TicketHolder with exactly 1 ticket, and three threads, T1 T2 T3. 

      The initial state of the system is T1 has the ticket checked out; SemaphoreTicketHolder::_tickets == 0. 

      T2 and T3 attempt to acquire tickets. None are available so they both block on the _tickets futex awaiting notification. 

      T1 returns its ticket, sees there are waiters, so it increments tickets to 1 and notifies _one waiter. 

      T2 receives the wakeup. It proceeds from the waitUntil here and checks for interrupt. It is interrupted so an exception is thrown and the stack is unwound. 

      The final state of the system is T3 is still waiting in the waitUntil and _waitersCount is 1, but _tickets is also 1 / there is a ticket available. 

       

      We are saved from the worst-case outcome of deadlocking this thread based on the periodic wakeups; each thread waits for ~500ms at a time, so it will eventually wake up and observe the ticket, taking the system out of the bad state. But, we're relying on a timeout here and adding additional latency to the operation by doing here. 

            Assignee:
            Unassigned Unassigned
            Reporter:
            george.wangensteen@mongodb.com George Wangensteen
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: