1 """Mutual exclusion -- for use with module sched
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.
11 Of course, no multi-threading is implied -- hence the funny interface
12 for lock, where a function is called once the lock is aquired.
15 from collections
import deque
19 """Create a new mutex -- initially unlocked."""
24 """Test the locked bit of the mutex."""
28 """Atomic test-and-set -- grab the lock if it is not set,
29 return True if it succeeded."""
36 def lock(self
, function
, argument
):
37 """Lock a mutex, call the function with supplied argument
38 when it is acquired. If the mutex is already locked, place
39 function and argument in the queue."""
43 self
.queue
.append((function
, argument
))
46 """Unlock a mutex. If the queue is not empty, call the next
47 function with its argument."""
49 function
, argument
= self
.queue
.popleft()