Catch situations where currentframe() returns None. See SF patch #1447410, this is...
[python.git] / Lib / mutex.py
blob5d35bdf6ab0928380da79003873638ff33c426c4
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.
13 """
15 from collections import deque
17 class mutex:
18 def __init__(self):
19 """Create a new mutex -- initially unlocked."""
20 self.locked = 0
21 self.queue = deque()
23 def test(self):
24 """Test the locked bit of the mutex."""
25 return self.locked
27 def testandset(self):
28 """Atomic test-and-set -- grab the lock if it is not set,
29 return True if it succeeded."""
30 if not self.locked:
31 self.locked = 1
32 return True
33 else:
34 return False
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."""
40 if self.testandset():
41 function(argument)
42 else:
43 self.queue.append((function, argument))
45 def unlock(self):
46 """Unlock a mutex. If the queue is not empty, call the next
47 function with its argument."""
48 if self.queue:
49 function, argument = self.queue.popleft()
50 function(argument)
51 else:
52 self.locked = 0