Example #1
0
 def test_demotion_no_waiters(self):
     lock = RWLock()
     try:
         with lock.exclusive:
             lock.acquireRead()
     finally:
         lock.release()
Example #2
0
    def test_wakeup_all_blocked_readers(self):
        lock = RWLock()
        readers = 10
        ready = Barrier(readers + 1)
        done = Barrier(readers + 1)
        threads = []

        def slow_reader():
            ready.wait(2)
            with lock.shared:
                time.sleep(0.5)
            done.wait(2)

        try:
            with lock.exclusive:
                # Start all readers
                for i in range(readers):
                    t = start_thread(slow_reader)
                    threads.append(t)
                # Wait until all readers are ready
                ready.wait(0.5)
                # Ensure that all readers are blocked
                time.sleep(0.5)
            # Releasing the write lock should wake up all the readers, holding
            # the lock for about 0.5 seconds.
            with self.assertNotRaises():
                done.wait(2)
        finally:
            for t in threads:
                t.join()
Example #3
0
 def test_fifo(self):
     lock = RWLock()
     threads = []
     try:
         with lock.shared:
             writer = LockingThread(lock.exclusive)
             writer.start()
             threads.append(writer)
             if not writer.ready.wait(2):
                 raise RuntimeError("Timeout waiting for writer thread")
             # Writer must block
             self.assertFalse(writer.acquired.wait(1))
             reader = LockingThread(lock.shared)
             reader.start()
             threads.append(reader)
             if not reader.ready.wait(1):
                 raise RuntimeError("Timeout waiting for reader thread")
             # Reader must block
             self.assertFalse(reader.acquired.wait(1))
         # Writer should get in before the reader
         self.assertTrue(writer.acquired.wait(1))
         writer.done.set()
         self.assertTrue(reader.acquired.wait(1))
     finally:
         for t in threads:
             t.stop()
Example #4
0
 def test_release_other_thread_write_lock(self):
     lock = RWLock()
     writer = LockingThread(lock.exclusive)
     with utils.running(writer):
         if not writer.acquired.wait(2):
             raise RuntimeError("Timeout waiting for writer thread")
         self.assertRaises(RuntimeError, lock.release)
Example #5
0
 def test_release_other_thread_read_lock(self):
     lock = RWLock()
     reader = LockingThread(lock.shared)
     with utils.running(reader):
         if not reader.acquired.wait(2):
             raise RuntimeError("Timeout waiting for reader thread")
         self.assertRaises(RuntimeError, lock.release)
Example #6
0
 def test_demotion_with_blocked_reader(self):
     lock = RWLock()
     reader = LockingThread(lock.shared)
     try:
         with lock.exclusive:
             reader.start()
             reader.ready.wait()
             # Ensure that reader is blocked
             if reader.acquired.wait(0.5):
                 raise RuntimeError("Reader could acquire the lock while "
                                    "holding a write lock")
             lock.acquireRead()
             # I hold both a read lock and a write lock now
         # I released the write lock. Having read lock, reader should get
         # the lock.
         self.assertTrue(reader.acquired.wait(0.5),
                         "Reader could not acuire the lock")
     finally:
         lock.release()
         reader.stop()
Example #7
0
 def test_exclusive_context_blocks_reader(self):
     lock = RWLock()
     reader = LockingThread(lock.shared)
     try:
         with lock.exclusive:
             reader.start()
             if not reader.ready.wait(2):
                 raise RuntimeError("Timeout waiting for reader thread")
             # Reader must block
             self.assertFalse(reader.acquired.wait(1))
     finally:
         reader.stop()
Example #8
0
 def test_shared_context_blocks_writer(self):
     lock = RWLock()
     writer = LockingThread(lock.exclusive)
     try:
         with lock.shared:
             writer.start()
             if not writer.ready.wait(2):
                 raise RuntimeError("Timeout waiting for writer thread")
             # Writer must block
             self.assertFalse(writer.acquired.wait(1))
     finally:
         writer.stop()
Example #9
0
 def test_demotion_with_blocked_writer(self):
     lock = RWLock()
     writer = LockingThread(lock.exclusive)
     try:
         with lock.exclusive:
             writer.start()
             writer.ready.wait()
             # Ensure that writer is blocked
             if writer.acquired.wait(0.5):
                 raise RuntimeError("Writer could acquire the lock while "
                                    "holding a write lock")
             lock.acquireRead()
             # I hold both a read lock and a write lock now
         # I release the write lock. Having read lock, writer must block
         self.assertFalse(
             writer.acquired.wait(0.5),
             "Writer acquired the lock while holding a read "
             "lock")
     finally:
         lock.release()
         try:
             # Writer must acquire now
             self.assertTrue(writer.acquired.wait(0.5))
         finally:
             writer.stop()
Example #10
0
 def test_demotion_no_waiters(self):
     lock = RWLock()
     try:
         with lock.exclusive:
             lock.acquireRead()
     finally:
         lock.release()
Example #11
0
 def test_concurrent_readers(self):
     lock = RWLock()
     readers = []
     try:
         for i in range(5):
             t = LockingThread(lock.shared)
             t.start()
             readers.append(t)
         for t in readers:
             self.assertTrue(t.acquired.wait(1))
     finally:
         for t in readers:
             t.stop()
Example #12
0
 def test_wakeup_blocked_reader(self):
     lock = RWLock()
     writer = LockingThread(lock.exclusive)
     with utils.running(writer):
         if not writer.acquired.wait(2):
             raise RuntimeError("Timeout waiting for writer thread")
         reader = LockingThread(lock.shared)
         with utils.running(reader):
             if not reader.ready.wait(2):
                 raise RuntimeError("Timeout waiting for reader thread")
             self.assertFalse(reader.acquired.wait(1))
             writer.done.set()
             self.assertTrue(reader.acquired.wait(2))
Example #13
0
    def test_fairness(self, writers, readers):
        lock = RWLock()
        ready = Barrier(writers + readers + 1)
        done = threading.Event()
        reads = [0] * readers
        writes = [0] * writers
        threads = []

        def read(slot):
            ready.wait()
            while not done.is_set():
                with lock.shared:
                    reads[slot] += 1

        def write(slot):
            ready.wait()
            while not done.is_set():
                with lock.exclusive:
                    writes[slot] += 1

        try:
            for i in range(readers):
                t = start_thread(read, i)
                threads.append(t)
            for i in range(writers):
                t = start_thread(write, i)
                threads.append(t)
            ready.wait(5)
            time.sleep(1)
        finally:
            done.set()
            for t in threads:
                t.join()

        print()
        # TODO: needed to work around bug in expandPermutations when using
        # decorated test methods.
        print("writers: %d readers: %d" % (writers, readers))

        avg_writes, med_writes, min_writes, max_writes = stats(writes)
        print("writes  avg=%.2f med=%d min=%d max=%d" %
              (avg_writes, med_writes, min_writes, max_writes))

        avg_reads, med_reads, min_reads, max_reads = stats(reads)
        print("reads   avg=%.2f med=%d min=%d max=%d" %
              (avg_reads, med_reads, min_reads, max_reads))

        avg_all = stats(writes + reads)[0]
        self.assertAlmostEqual(avg_reads, avg_writes, delta=avg_all / 10)
Example #14
0
 def test_demotion_with_blocked_writer(self):
     lock = RWLock()
     writer = LockingThread(lock.exclusive)
     try:
         with lock.exclusive:
             writer.start()
             writer.ready.wait()
             # Ensure that writer is blocked
             if writer.acquired.wait(0.5):
                 raise RuntimeError("Writer could acquire the lock while "
                                    "holding a write lock")
             lock.acquireRead()
             # I hold both a read lock and a write lock now
         # I release the write lock. Having read lock, writer must block
         self.assertFalse(writer.acquired.wait(0.5),
                          "Writer acquired the lock while holding a read "
                          "lock")
     finally:
         lock.release()
         try:
             # Writer must acquire now
             self.assertTrue(writer.acquired.wait(0.5))
         finally:
             writer.stop()
Example #15
0
 def test_demotion_with_blocked_reader(self):
     lock = RWLock()
     reader = LockingThread(lock.shared)
     try:
         with lock.exclusive:
             reader.start()
             reader.ready.wait()
             # Ensure that reader is blocked
             if reader.acquired.wait(0.5):
                 raise RuntimeError("Reader could acquire the lock while "
                                    "holding a write lock")
             lock.acquireRead()
             # I hold both a read lock and a write lock now
         # I released the write lock. Having read lock, reader shold get the
         # lock.
         self.assertTrue(reader.acquired.wait(0.5),
                         "Reader could not acuire the lock")
     finally:
         lock.release()
         reader.stop()
Example #16
0
 def test_promotion_forbidden(self):
     lock = RWLock()
     with lock.shared:
         self.assertRaises(RuntimeError, lock.acquireWrite)
Example #17
0
 def test_shared_context_allows_reader(self):
     lock = RWLock()
     with lock.shared:
         reader = LockingThread(lock.shared)
         with utils.running(reader):
             self.assertTrue(reader.acquired.wait(1))
Example #18
0
 def test_recursive_write_lock(self):
     lock = RWLock()
     with lock.exclusive:
         with lock.exclusive:
             pass
Example #19
0
 def test_recursive_read_lock(self):
     lock = RWLock()
     with lock.shared:
         with lock.shared:
             pass