Fixed an issue where some access checks would fail due to missing arguments.
This happens when an org document is being checked for write access when trying to show the edit link on the document's show page.
"""
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()