diff options
Diffstat (limited to 'google_appengine/lib/django/django/utils/synch.py')
-rwxr-xr-x | google_appengine/lib/django/django/utils/synch.py | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/google_appengine/lib/django/django/utils/synch.py b/google_appengine/lib/django/django/utils/synch.py new file mode 100755 index 0000000..6fcd813 --- /dev/null +++ b/google_appengine/lib/django/django/utils/synch.py @@ -0,0 +1,88 @@ +""" +Synchronization primitives: + + - reader-writer lock (preference to writers) + +(Contributed to Django by eugene@lazutkin.com) +""" + +try: + import threading +except ImportError: + import dummy_threading as threading + +class RWLock: + """ + Classic implementation of reader-writer lock with preference to writers. + + Readers can access a resource simultaneously. + Writers get an exclusive access. + + API is self-descriptive: + reader_enters() + reader_leaves() + writer_enters() + writer_leaves() + """ + + def __init__(self): + self.mutex = threading.RLock() + self.can_read = threading.Semaphore(0) + self.can_write = threading.Semaphore(0) + self.active_readers = 0 + self.active_writers = 0 + self.waiting_readers = 0 + self.waiting_writers = 0 + + def reader_enters(self): + self.mutex.acquire() + try: + if self.active_writers == 0 and self.waiting_writers == 0: + self.active_readers += 1 + self.can_read.release() + else: + self.waiting_readers += 1 + finally: + self.mutex.release() + self.can_read.acquire() + + def reader_leaves(self): + self.mutex.acquire() + try: + self.active_readers -= 1 + if self.active_readers == 0 and self.waiting_writers != 0: + self.active_writers += 1 + self.waiting_writers -= 1 + self.can_write.release() + finally: + self.mutex.release() + + def writer_enters(self): + self.mutex.acquire() + try: + if self.active_writers == 0 and self.waiting_writers == 0 and self.active_readers == 0: + self.active_writers += 1 + self.can_write.release() + else: + self.waiting_writers += 1 + finally: + self.mutex.release() + self.can_write.acquire() + + def writer_leaves(self): + self.mutex.acquire() + try: + self.active_writers -= 1 + if self.waiting_writers != 0: + self.active_writers += 1 + self.waiting_writers -= 1 + self.can_write.release() + elif self.waiting_readers != 0: + t = self.waiting_readers + self.waiting_readers = 0 + self.active_readers += t + while t > 0: + self.can_read.release() + t -= 1 + finally: + self.mutex.release() |