Django

Code

Ticket #515: synch.py

File synch.py, 2.4 kB (added by eugene@lazutkin.com, 3 years ago)

new file django/utils/synch.py

Line 
1 """
2
3 Synchronization primitives:
4     
5     - reader-writer lock (preference to writers)
6
7 """
8
9 import threading
10
11 class 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()