github.com/google/grumpy@v0.0.0-20171122020858-3ec87959189c/third_party/stdlib/mutex.py (about)

     1  """Mutual exclusion -- for use with module sched
     2  
     3  A mutex has two pieces of state -- a 'locked' bit and a queue.
     4  When the mutex is not locked, the queue is empty.
     5  Otherwise, the queue contains 0 or more (function, argument) pairs
     6  representing functions (or methods) waiting to acquire the lock.
     7  When the mutex is unlocked while the queue is not empty,
     8  the first queue entry is removed and its function(argument) pair called,
     9  implying it now has the lock.
    10  
    11  Of course, no multi-threading is implied -- hence the funny interface
    12  for lock, where a function is called once the lock is acquired.
    13  """
    14  from warnings import warnpy3k
    15  warnpy3k("the mutex module has been removed in Python 3.0", stacklevel=2)
    16  del warnpy3k
    17  
    18  from collections import deque
    19  
    20  class mutex(object):
    21      def __init__(self):
    22          """Create a new mutex -- initially unlocked."""
    23          self.locked = False
    24          self.queue = deque()
    25  
    26      def test(self):
    27          """Test the locked bit of the mutex."""
    28          return self.locked
    29  
    30      def testandset(self):
    31          """Atomic test-and-set -- grab the lock if it is not set,
    32          return True if it succeeded."""
    33          if not self.locked:
    34              self.locked = True
    35              return True
    36          else:
    37              return False
    38  
    39      def lock(self, function, argument):
    40          """Lock a mutex, call the function with supplied argument
    41          when it is acquired.  If the mutex is already locked, place
    42          function and argument in the queue."""
    43          if self.testandset():
    44              function(argument)
    45          else:
    46              self.queue.append((function, argument))
    47  
    48      def unlock(self):
    49          """Unlock a mutex.  If the queue is not empty, call the next
    50          function with its argument."""
    51          if self.queue:
    52              function, argument = self.queue.popleft()
    53              function(argument)
    54          else:
    55              self.locked = False