Ticket #515: synch.py

File synch.py, 2.4 KB (added by eugene@…, 19 years ago)

new file django/utils/synch.py

Line 
1"""
2
3Synchronization primitives:
4
5 - reader-writer lock (preference to writers)
6
7"""
8
9import threading
10
11class RWLock:
12 """
13 Classic implementation of reader-writer lock with preference to writers.
14
15 Readers can access a resource simultaneously.
16 Writers get an exclusive access.
17
18 API is self-descriptive:
19 reader_enters()
20 reader_leaves()
21 writer_enters()
22 writer_leaves()
23 """
24
25 def __init__(self):
26 self.mutex = threading.RLock()
27 self.can_read = threading.Semaphore(0)
28 self.can_write = threading.Semaphore(0)
29 self.active_readers = 0
30 self.active_writers = 0
31 self.waiting_readers = 0
32 self.waiting_writers = 0
33
34 def reader_enters(self):
35 self.mutex.acquire()
36 try:
37 if self.active_writers == 0 and self.waiting_writers == 0:
38 self.active_readers += 1
39 self.can_read.release()
40 else:
41 self.waiting_readers += 1
42 finally:
43 self.mutex.release()
44 self.can_read.acquire()
45
46 def reader_leaves(self):
47 self.mutex.acquire()
48 try:
49 self.active_readers -= 1
50 if self.active_readers == 0 and self.waiting_writers != 0:
51 self.active_writers += 1
52 self.waiting_writers -= 1
53 self.can_write.release()
54 finally:
55 self.mutex.release()
56
57 def writer_enters(self):
58 self.mutex.acquire()
59 try:
60 if self.active_writers == 0 and self.waiting_writers == 0 and self.active_readers == 0:
61 self.active_writers += 1
62 self.can_write.release()
63 else:
64 self.waiting_writers += 1
65 finally:
66 self.mutex.release()
67 self.can_write.acquire()
68
69 def writer_leaves(self):
70 self.mutex.acquire()
71 try:
72 self.active_writers -= 1
73 if self.waiting_writers != 0:
74 self.active_writers += 1
75 self.waiting_writers -= 1
76 self.can_write.release()
77 elif self.waiting_readers != 0:
78 t = self.waiting_readers
79 self.waiting_readers = 0
80 self.active_readers += t
81 while t > 0:
82 self.can_read.release()
83 t -= 1
84 finally:
85 self.mutex.release()
Back to Top