diff -r 57b4279d8c4e -r 03e267d67478 app/django/utils/synch.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/django/utils/synch.py Fri Jul 18 18:22:23 2008 +0000 @@ -0,0 +1,87 @@ +""" +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()