From d67b9d08ddcf906240e5d3f2b0b118a7254b4390 Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Sat, 6 Jun 2015 20:42:28 -0700 Subject: [PATCH] Ensure writer -> reader -> writer r/w lock acquisition Fixes issue #4 --- fasteners/lock.py | 5 +++-- fasteners/tests/test_lock.py | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fasteners/lock.py b/fasteners/lock.py index 55202f9..f9969dc 100644 --- a/fasteners/lock.py +++ b/fasteners/lock.py @@ -216,10 +216,11 @@ class ReaderWriterLock(object): a lock. """ me = self._current_thread() - if self.is_reader(): + i_am_writer = self.is_writer(check_pending=False) + if self.is_reader() and not i_am_writer: raise RuntimeError("Reader %s to writer privilege" " escalation not allowed" % me) - if self.is_writer(check_pending=False): + if i_am_writer: # Already the writer; this allows for basic reentrancy. yield self else: diff --git a/fasteners/tests/test_lock.py b/fasteners/tests/test_lock.py index 4972928..7d3b234 100644 --- a/fasteners/tests/test_lock.py +++ b/fasteners/tests/test_lock.py @@ -315,6 +315,15 @@ class ReadWriteLockTest(test.TestCase): self.assertEqual(5, len(writers)) self.assertEqual(10, len(readers)) + def test_writer_reader_writer(self): + lock = fasteners.ReaderWriterLock() + with lock.write_lock(): + self.assertTrue(lock.is_writer()) + with lock.read_lock(): + self.assertTrue(lock.is_reader()) + with lock.write_lock(): + self.assertTrue(lock.is_writer()) + def test_single_reader_writer(self): results = [] lock = fasteners.ReaderWriterLock()