Skip to content
Snippets Groups Projects
Commit 8c811986 authored by Michael Hanselmann's avatar Michael Hanselmann
Browse files

locking: Method to check if LockSet is fully acquired


A new method is added to check whether the LockSet-internal lock is
held. This is the case after LockSet.acquire was called with
locking.ALL_SET.

Unit tests are updated, including one where the list of names must be
empty.

Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent 46cde471
No related branches found
No related tags found
No related merge requests found
...@@ -1033,6 +1033,18 @@ class LockSet: ...@@ -1033,6 +1033,18 @@ class LockSet:
else: else:
return False return False
def owning_all(self):
"""Checks whether current thread owns internal lock.
Holding the internal lock is equivalent with holding all locks in the set
(the opposite does not necessarily hold as it can not be easily
determined). L{add} and L{remove} require the internal lock.
@rtype: boolean
"""
return self.__lock.is_owned()
def _add_owned(self, name=None): def _add_owned(self, name=None):
"""Note the current thread owns the given lock""" """Note the current thread owns the given lock"""
if name is None: if name is None:
...@@ -1620,6 +1632,14 @@ class GanetiLockManager: ...@@ -1620,6 +1632,14 @@ class GanetiLockManager:
""" """
return self.__keyring[level].check_owned(names, shared=shared) return self.__keyring[level].check_owned(names, shared=shared)
def owning_all(self, level):
"""Checks whether current thread owns all locks at a certain level.
@see: L{LockSet.owning_all}
"""
return self.__keyring[level].owning_all()
def _upper_owned(self, level): def _upper_owned(self, level):
"""Check that we don't own any lock at a level greater than the given one. """Check that we don't own any lock at a level greater than the given one.
......
...@@ -1606,6 +1606,7 @@ class TestLockSet(_ThreadedTestCase): ...@@ -1606,6 +1606,7 @@ class TestLockSet(_ThreadedTestCase):
self.assertEqual(self.ls.acquire(None), set(["one", "two", "three"])) self.assertEqual(self.ls.acquire(None), set(["one", "two", "three"]))
# now empty it... # now empty it...
self.ls.remove(["one", "two", "three"]) self.ls.remove(["one", "two", "three"])
self.assertFalse(self.ls._names())
# and adds/locks by another thread still wait # and adds/locks by another thread still wait
self._addThread(target=self._doAddSet, args=(["nine"])) self._addThread(target=self._doAddSet, args=(["nine"]))
self._addThread(target=self._doLockSet, args=(None, 1)) self._addThread(target=self._doLockSet, args=(None, 1))
...@@ -1713,6 +1714,7 @@ class TestLockSet(_ThreadedTestCase): ...@@ -1713,6 +1714,7 @@ class TestLockSet(_ThreadedTestCase):
def testDowngradeEverything(self): def testDowngradeEverything(self):
self.assertEqual(self.ls.acquire(locking.ALL_SET, shared=0), self.assertEqual(self.ls.acquire(locking.ALL_SET, shared=0),
set(["one", "two", "three"])) set(["one", "two", "three"]))
self.assertTrue(self.ls.owning_all())
# Ensure all locks are now owned in exclusive mode # Ensure all locks are now owned in exclusive mode
for name in self.ls._names(): for name in self.ls._names():
...@@ -1725,6 +1727,8 @@ class TestLockSet(_ThreadedTestCase): ...@@ -1725,6 +1727,8 @@ class TestLockSet(_ThreadedTestCase):
for name in self.ls._names(): for name in self.ls._names():
self.assertTrue(self.ls.check_owned(name, shared=1)) self.assertTrue(self.ls.check_owned(name, shared=1))
self.assertTrue(self.ls.owning_all())
def testPriority(self): def testPriority(self):
def _Acquire(prev, next, name, priority, success_fn): def _Acquire(prev, next, name, priority, success_fn):
prev.wait() prev.wait()
...@@ -1890,12 +1894,16 @@ class TestGanetiLockManager(_ThreadedTestCase): ...@@ -1890,12 +1894,16 @@ class TestGanetiLockManager(_ThreadedTestCase):
set(self.nodes)) set(self.nodes))
self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE), self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE),
set(self.nodes)) set(self.nodes))
self.assertTrue(self.GL.owning_all(locking.LEVEL_INSTANCE))
self.assertTrue(self.GL.owning_all(locking.LEVEL_NODEGROUP))
self.assertTrue(self.GL.owning_all(locking.LEVEL_NODE))
self.GL.release(locking.LEVEL_NODE) self.GL.release(locking.LEVEL_NODE)
self.GL.release(locking.LEVEL_NODEGROUP) self.GL.release(locking.LEVEL_NODEGROUP)
self.GL.release(locking.LEVEL_INSTANCE) self.GL.release(locking.LEVEL_INSTANCE)
self.GL.release(locking.LEVEL_CLUSTER) self.GL.release(locking.LEVEL_CLUSTER)
def testAcquireWholeAndPartial(self): def testAcquireWholeAndPartial(self):
self.assertFalse(self.GL.owning_all(locking.LEVEL_INSTANCE))
self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1) self.GL.acquire(locking.LEVEL_CLUSTER, ["BGL"], shared=1)
self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None), self.assertEquals(self.GL.acquire(locking.LEVEL_INSTANCE, None),
set(self.instances)) set(self.instances))
...@@ -1905,6 +1913,8 @@ class TestGanetiLockManager(_ThreadedTestCase): ...@@ -1905,6 +1913,8 @@ class TestGanetiLockManager(_ThreadedTestCase):
set(["n2"])) set(["n2"]))
self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE), self.assertEquals(self.GL.list_owned(locking.LEVEL_NODE),
set(["n2"])) set(["n2"]))
self.assertTrue(self.GL.owning_all(locking.LEVEL_INSTANCE))
self.assertFalse(self.GL.owning_all(locking.LEVEL_NODE))
self.GL.release(locking.LEVEL_NODE) self.GL.release(locking.LEVEL_NODE)
self.GL.release(locking.LEVEL_INSTANCE) self.GL.release(locking.LEVEL_INSTANCE)
self.GL.release(locking.LEVEL_CLUSTER) self.GL.release(locking.LEVEL_CLUSTER)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment