From 2419060dfa640186dc22cb461a21d0eaf0b32307 Mon Sep 17 00:00:00 2001 From: Guido Trotter <ultrotter@google.com> Date: Wed, 30 Sep 2009 18:30:07 +0100 Subject: [PATCH] Abstract "base" condition code in a separate class Each condition has an underlying lock, the acquire and release methods, and a few helper methods to check that it's called in the proper way. Abstract them to a separate class so we can have more than one without duplicating this code. Signed-off-by: Guido Trotter <ultrotter@google.com> Reviewed-by: Michael Hanselmann <hansmi@google.com> --- lib/locking.py | 86 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 34 deletions(-) diff --git a/lib/locking.py b/lib/locking.py index f7a62d279..1e14f6588 100644 --- a/lib/locking.py +++ b/lib/locking.py @@ -103,6 +103,55 @@ class _SingleActionPipeConditionWaiter(object): remaining_time = start_time + timeout - time.time() +class _BaseCondition(object): + """Base class containing common code for conditions. + + Some of this code is taken from python's threading module. + + """ + __slots__ = [ + "_lock", + "acquire", + "release", + ] + + def __init__(self, lock): + """Constructor for _BaseCondition. + + @type lock: L{threading.Lock} + @param lock: condition base lock + + """ + object.__init__(self) + + # Recursive locks are not supported + assert not hasattr(lock, "_acquire_restore") + assert not hasattr(lock, "_release_save") + + self._lock = lock + + # Export the lock's acquire() and release() methods + self.acquire = lock.acquire + self.release = lock.release + + def _is_owned(self): + """Check whether lock is owned by current thread. + + """ + if self._lock.acquire(0): + self._lock.release() + return False + + return True + + def _check_owned(self): + """Raise an exception if the current thread doesn't own the lock. + + """ + if not self._is_owned(): + raise RuntimeError("cannot work with un-aquired lock") + + class _SingleActionPipeCondition(object): """Wrapper around a pipe for usage inside conditions. @@ -223,7 +272,7 @@ class _SingleActionPipeCondition(object): self._Cleanup() -class _PipeCondition(object): +class _PipeCondition(_BaseCondition): """Group-only non-polling condition with counters. This condition class uses pipes and poll, internally, to be able to wait for @@ -233,12 +282,9 @@ class _PipeCondition(object): there are any waiting threads. """ - __slots__ = [ - "_lock", + __slots__ = _BaseCondition.__slots__ + [ "_nwaiters", "_pipe", - "acquire", - "release", ] _pipe_class = _SingleActionPipeCondition @@ -247,38 +293,10 @@ class _PipeCondition(object): """Initializes this class. """ - object.__init__(self) - - # Recursive locks are not supported - assert not hasattr(lock, "_acquire_restore") - assert not hasattr(lock, "_release_save") - - self._lock = lock - - # Export the lock's acquire() and release() methods - self.acquire = lock.acquire - self.release = lock.release - + _BaseCondition.__init__(self, lock) self._nwaiters = 0 self._pipe = None - def _is_owned(self): - """Check whether lock is owned by current thread. - - """ - if self._lock.acquire(0): - self._lock.release() - return False - - return True - - def _check_owned(self): - """Raise an exception if the current thread doesn't own the lock. - - """ - if not self._is_owned(): - raise RuntimeError("cannot work with un-aquired lock") - def wait(self, timeout=None): """Wait for a notification. -- GitLab