Merge "Fix dummy lock missing pending_writers method"

This commit is contained in:
Jenkins
2014-02-24 06:52:01 +00:00
committed by Gerrit Code Review
2 changed files with 52 additions and 21 deletions

View File

@@ -118,7 +118,7 @@ class ReadWriteLockTest(test.TestCase):
def double_reader():
with lock.read_lock():
active.set()
while lock.pending_writers == 0:
while not lock.has_pending_writers:
time.sleep(0.001)
with lock.read_lock():
activated.append(lock.owner)

View File

@@ -19,6 +19,7 @@
# pulls in oslo.cfg) and is reduced to only what taskflow currently wants to
# use from that code.
import abc
import collections
import contextlib
import errno
@@ -27,6 +28,8 @@ import os
import threading
import time
import six
from taskflow.utils import misc
from taskflow.utils import threading_utils as tu
@@ -63,7 +66,47 @@ def locked(*args, **kwargs):
return decorator
class ReaderWriterLock(object):
@six.add_metaclass(abc.ABCMeta)
class _ReaderWriterLockBase(object):
"""Base class for reader/writer lock implementations."""
@abc.abstractproperty
def has_pending_writers(self):
"""Returns if there are writers waiting to become the *one* writer."""
@abc.abstractmethod
def is_writer(self, check_pending=True):
"""Returns if the caller is the active writer or a pending writer."""
@abc.abstractproperty
def owner(self):
"""Returns whether the lock is locked by a writer or reader."""
@abc.abstractmethod
def is_reader(self):
"""Returns if the caller is one of the readers."""
@abc.abstractmethod
def read_lock(self):
"""Context manager that grants a read lock.
Will wait until no active or pending writers.
Raises a RuntimeError if an active or pending writer tries to acquire
a read lock.
"""
@abc.abstractmethod
def write_lock(self):
"""Context manager that grants a write lock.
Will wait until no active readers. Blocks readers after acquiring.
Raises a RuntimeError if an active reader attempts to acquire a lock.
"""
class ReaderWriterLock(_ReaderWriterLockBase):
"""A reader/writer lock.
This lock allows for simultaneous readers to exist but only one writer
@@ -85,15 +128,14 @@ class ReaderWriterLock(object):
self._cond = threading.Condition()
@property
def pending_writers(self):
def has_pending_writers(self):
self._cond.acquire()
try:
return len(self._pending_writers)
return bool(self._pending_writers)
finally:
self._cond.release()
def is_writer(self, check_pending=True):
"""Returns if the caller is the active writer or a pending writer."""
self._cond.acquire()
try:
me = tu.get_ident()
@@ -108,7 +150,6 @@ class ReaderWriterLock(object):
@property
def owner(self):
"""Returns whether the lock is locked by a writer or reader."""
self._cond.acquire()
try:
if self._writer is not None:
@@ -120,7 +161,6 @@ class ReaderWriterLock(object):
self._cond.release()
def is_reader(self):
"""Returns if the caller is one of the readers."""
self._cond.acquire()
try:
return tu.get_ident() in self._readers
@@ -129,13 +169,6 @@ class ReaderWriterLock(object):
@contextlib.contextmanager
def read_lock(self):
"""Grants a read lock.
Will wait until no active or pending writers.
Raises a RuntimeError if an active or pending writer tries to acquire
a read lock.
"""
me = tu.get_ident()
if self.is_writer():
raise RuntimeError("Writer %s can not acquire a read lock"
@@ -168,12 +201,6 @@ class ReaderWriterLock(object):
@contextlib.contextmanager
def write_lock(self):
"""Grants a write lock.
Will wait until no active readers. Blocks readers after acquiring.
Raises a RuntimeError if an active reader attempts to acquire a lock.
"""
me = tu.get_ident()
if self.is_reader():
raise RuntimeError("Reader %s to writer privilege"
@@ -205,7 +232,7 @@ class ReaderWriterLock(object):
self._cond.release()
class DummyReaderWriterLock(object):
class DummyReaderWriterLock(_ReaderWriterLockBase):
"""A dummy reader/writer lock that doesn't lock anything but provides same
functions as a normal reader/writer lock class.
"""
@@ -227,6 +254,10 @@ class DummyReaderWriterLock(object):
def is_writer(self):
return False
@property
def has_pending_writers(self):
return False
class MultiLock(object):
"""A class which can attempt to obtain many locks at once and release