Revision 113359fe

b/lib/locking.py
562 562
    self.__lock.acquire()
563 563
    try:
564 564
      # Order is important: __find_first_pending_queue modifies __pending
565
      return not (self.__find_first_pending_queue() or
565
      (_, prioqueue) = self.__find_first_pending_queue()
566

  
567
      return not (prioqueue or
566 568
                  self.__pending or
567 569
                  self.__pending_by_prio or
568 570
                  self.__pending_shared)
......
596 598
    while self.__pending:
597 599
      (priority, prioqueue) = self.__pending[0]
598 600

  
599
      if not prioqueue:
600
        heapq.heappop(self.__pending)
601
        del self.__pending_by_prio[priority]
602
        assert priority not in self.__pending_shared
603
        continue
604

  
605 601
      if prioqueue:
606
        return prioqueue
602
        return (priority, prioqueue)
607 603

  
608
    return None
604
      # Remove empty queue
605
      heapq.heappop(self.__pending)
606
      del self.__pending_by_prio[priority]
607
      assert priority not in self.__pending_shared
608

  
609
    return (None, None)
609 610

  
610 611
  def __is_on_top(self, cond):
611 612
    """Checks whether the passed condition is on top of the queue.
......
613 614
    The caller must make sure the queue isn't empty.
614 615

  
615 616
    """
616
    return cond == self.__find_first_pending_queue()[0]
617
    (_, prioqueue) = self.__find_first_pending_queue()
618

  
619
    return cond == prioqueue[0]
617 620

  
618 621
  def __acquire_unlocked(self, shared, timeout, priority):
619 622
    """Acquire a shared lock.
......
690 693
      if not wait_condition.has_waiting():
691 694
        prioqueue.remove(wait_condition)
692 695
        if wait_condition.shared:
693
          del self.__pending_shared[priority]
696
          # Remove from list of shared acquires if it wasn't while releasing
697
          # (e.g. on lock deletion)
698
          self.__pending_shared.pop(priority, None)
694 699

  
695 700
    return False
696 701

  
......
741 746
        self.__shr.remove(threading.currentThread())
742 747

  
743 748
      # Notify topmost condition in queue
744
      prioqueue = self.__find_first_pending_queue()
749
      (priority, prioqueue) = self.__find_first_pending_queue()
745 750
      if prioqueue:
746
        prioqueue[0].notifyAll()
751
        cond = prioqueue[0]
752
        cond.notifyAll()
753
        if cond.shared:
754
          # Prevent further shared acquires from sneaking in while waiters are
755
          # notified
756
          self.__pending_shared.pop(priority, None)
747 757

  
748 758
    finally:
749 759
      self.__lock.release()

Also available in: Unified diff