add a pybench test for complex function calls (part of #1819)
[python.git] / Lib / mutex.py
blob9e6b8d43c7b5b3258ac0dfcfba040050df1d92aa
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 """
14 from warnings import warnpy3k
15 warnpy3k("the mutex module has been removed in Python 3.0", stacklevel=2)
16 del warnpy3k
18 from collections import deque
20 class mutex:
21 def __init__(self):
22 """Create a new mutex -- initially unlocked."""
23 self.locked = 0
24 self.queue = deque()
26 def test(self):
27 """Test the locked bit of the mutex."""
28 return self.locked
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 = 1
35 return True
36 else:
37 return False
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))
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 = 0