69 lines
1.8 KiB
Python
69 lines
1.8 KiB
Python
from threading import RLock, Condition
|
|
|
|
# This implementation was adapted from https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock
|
|
|
|
class RWLockWrite():
|
|
''' write preferring readers-wirter lock '''
|
|
|
|
def __init__(self):
|
|
self._lock = RLock()
|
|
self._cond = Condition(self._lock)
|
|
self._active_readers = 0
|
|
self._waiting_writers = 0
|
|
self._writer_active = False
|
|
|
|
def aquire_read(self):
|
|
with self._lock:
|
|
while self._waiting_writers > 0 or self._writer_active:
|
|
self._cond.wait()
|
|
self._active_readers += 1
|
|
|
|
def release_read(self):
|
|
with self._lock:
|
|
self._active_readers -= 1
|
|
if self._active_readers == 0:
|
|
self._cond.notify_all()
|
|
|
|
def aquire_write(self):
|
|
with self._lock:
|
|
self._waiting_writers += 1
|
|
while self._active_readers > 0 or self._writer_active:
|
|
self._cond.wait()
|
|
self._waiting_writers -= 1
|
|
self._writer_active = True
|
|
|
|
def release_write(self):
|
|
with self._lock:
|
|
self._writer_active = False
|
|
self._cond.notify_all()
|
|
|
|
def gen_rlock(self):
|
|
return ReadRWLock(self)
|
|
|
|
def gen_wlock(self):
|
|
return WriteRWLock(self)
|
|
|
|
class ReadRWLock():
|
|
|
|
def __init__(self, rwlock):
|
|
self.rwlock = rwlock
|
|
|
|
def __enter__(self):
|
|
self.rwlock.aquire_read()
|
|
|
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
self.rwlock.release_read()
|
|
return False
|
|
|
|
class WriteRWLock():
|
|
|
|
def __init__(self, rwlock):
|
|
self.rwlock = rwlock
|
|
|
|
def __enter__(self):
|
|
self.rwlock.aquire_write()
|
|
|
|
def __exit__(self, exc_type, exc_value, traceback):
|
|
self.rwlock.release_write()
|
|
return False
|