From 1a4e32d0777803ce43331252c4567003a313678a Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Wed, 9 Jun 2010 19:18:24 +0100
Subject: [PATCH] SharedLock _acquire_restore and _release_save

If a shared lock is used inside a condition, we need to make sure that
it's reacquired in the same way as it was originally, after the wait.

Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/locking.py                  |  8 ++++++++
 test/ganeti.locking_unittest.py | 21 +++++++++++++++++++++
 2 files changed, 29 insertions(+)

diff --git a/lib/locking.py b/lib/locking.py
index 3e25917c4..19c41eba6 100644
--- a/lib/locking.py
+++ b/lib/locking.py
@@ -692,6 +692,14 @@ class SharedLock(object):
     finally:
       self.__lock.release()
 
+  def _release_save(self):
+    shared = self.__is_sharer()
+    self.release()
+    return shared
+
+  def _acquire_restore(self, shared):
+    self.acquire(shared=shared)
+
 
 # Whenever we want to acquire a full LockSet we pass None as the value
 # to acquire.  Hide this behind this nicely named constant.
diff --git a/test/ganeti.locking_unittest.py b/test/ganeti.locking_unittest.py
index 170e8197b..f767ccec9 100755
--- a/test/ganeti.locking_unittest.py
+++ b/test/ganeti.locking_unittest.py
@@ -698,6 +698,27 @@ class TestSharedLock(_ThreadedTestCase):
     self.assertRaises(Queue.Empty, self.done.get_nowait)
 
 
+class TestSharedLockInCondition(_ThreadedTestCase):
+  """SharedLock as a condition lock tests"""
+
+  def setUp(self):
+    _ThreadedTestCase.setUp(self)
+    self.sl = locking.SharedLock()
+    self.cond = threading.Condition(self.sl)
+
+  def testKeepMode(self):
+    self.cond.acquire(shared=1)
+    self.assert_(self.sl._is_owned(shared=1))
+    self.cond.wait(0)
+    self.assert_(self.sl._is_owned(shared=1))
+    self.cond.release()
+    self.cond.acquire(shared=0)
+    self.assert_(self.sl._is_owned(shared=0))
+    self.cond.wait(0)
+    self.assert_(self.sl._is_owned(shared=0))
+    self.cond.release()
+
+
 class TestSSynchronizedDecorator(_ThreadedTestCase):
   """Shared Lock Synchronized decorator test"""
 
-- 
GitLab