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