py-cvs-rel2_1 (Rev 1.2) merge
[python/dscho.git] / Lib / mutex.py
blob2348a2e0041d753dfbfa37f8e4c195c99ddec1f9
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 class mutex:
16 def __init__(self):
17 """Create a new mutex -- initially unlocked."""
18 self.locked = 0
19 self.queue = []
21 def test(self):
22 """Test the locked bit of the mutex."""
23 return self.locked
25 def testandset(self):
26 """Atomic test-and-set -- grab the lock if it is not set,
27 return true if it succeeded."""
28 if not self.locked:
29 self.locked = 1
30 return 1
31 else:
32 return 0
34 def lock(self, function, argument):
35 """Lock a mutex, call the function with supplied argument
36 when it is acquired. If the mutex is already locked, place
37 function and argument in the queue."""
38 if self.testandset():
39 function(argument)
40 else:
41 self.queue.append((function, argument))
43 def unlock(self):
44 """Unlock a mutex. If the queue is not empty, call the next
45 function with its argument."""
46 if self.queue:
47 function, argument = self.queue[0]
48 del self.queue[0]
49 function(argument)
50 else:
51 self.locked = 0