X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/56452af77890c7b98c9456a42a692315e4ad70bf..728489a31609c62e5f65660cf2430dcd6a361b3c:/lib/locking.py diff --git a/lib/locking.py b/lib/locking.py index 103d645..aeafd3f 100644 --- a/lib/locking.py +++ b/lib/locking.py @@ -141,8 +141,12 @@ class _SingleNotifyPipeConditionWaiter(object): while True: remaining_time = running_timeout.Remaining() - if remaining_time is not None and remaining_time < 0.0: - break + if remaining_time is not None: + if remaining_time < 0.0: + break + + # Our calculation uses seconds, poll() wants milliseconds + remaining_time *= 1000 try: result = self._poller.poll(remaining_time) @@ -216,7 +220,7 @@ class SingleNotifyPipeCondition(_BaseCondition): """ - __slots__ = _BaseCondition.__slots__ + [ + __slots__ = [ "_poller", "_read_fd", "_write_fd", @@ -309,7 +313,7 @@ class PipeCondition(_BaseCondition): there are any waiting threads. """ - __slots__ = _BaseCondition.__slots__ + [ + __slots__ = [ "_nwaiters", "_single_condition", ] @@ -600,7 +604,7 @@ class SharedLock(object): def acquire(self, shared=0, timeout=None, test_notify=None): """Acquire a shared lock. - @type shared: int + @type shared: integer (0/1) used as a boolean @param shared: whether to acquire in shared mode; by default an exclusive lock will be acquired @type timeout: float @@ -713,6 +717,7 @@ class LockSet: def __init__(self, members=None): """Constructs a new LockSet. + @type members: list of strings @param members: initial members of the set """ @@ -811,8 +816,10 @@ class LockSet: def acquire(self, names, timeout=None, shared=0, test_notify=None): """Acquire a set of resource locks. + @type names: list of strings (or string) @param names: the names of the locks which shall be acquired (special lock names, or instance/node names) + @type shared: integer (0/1) used as a boolean @param shared: whether to acquire in shared mode; by default an exclusive lock will be acquired @type timeout: float or None @@ -841,8 +848,6 @@ class LockSet: # Support passing in a single resource to acquire rather than many if isinstance(names, basestring): names = [names] - else: - names = sorted(names) return self.__acquire_inner(names, False, shared, running_timeout.Remaining, test_notify) @@ -891,11 +896,11 @@ class LockSet: # First we look the locks up on __lockdict. We have no way of being sure # they will still be there after, but this makes it a lot faster should - # just one of them be the already wrong - for lname in utils.UniqueSequence(names): + # just one of them be the already wrong. Using a sorted sequence to prevent + # deadlocks. + for lname in sorted(utils.UniqueSequence(names)): try: lock = self.__lockdict[lname] # raises KeyError if lock is not there - acquire_list.append((lname, lock)) except KeyError: if want_all: # We are acquiring all the set, it doesn't matter if this particular @@ -904,6 +909,8 @@ class LockSet: raise errors.LockError("Non-existing lock in set (%s)" % lname) + acquire_list.append((lname, lock)) + # This will hold the locknames we effectively acquired. acquired = set() @@ -968,6 +975,7 @@ class LockSet: You must have acquired the locks, either in shared or in exclusive mode, before releasing them. + @type names: list of strings, or None @param names: the names of the locks which shall be released (defaults to all the locks acquired at that level). @@ -1001,8 +1009,11 @@ class LockSet: def add(self, names, acquired=0, shared=0): """Add a new set of elements to the set + @type names: list of strings @param names: names of the new elements to add + @type acquired: integer (0/1) used as a boolean @param acquired: pre-acquire the new resource? + @type shared: integer (0/1) used as a boolean @param shared: is the pre-acquisition shared? """ @@ -1062,6 +1073,7 @@ class LockSet: You can either not hold anything in the lockset or already hold a superset of the elements you want to delete, exclusively. + @type names: list of strings @param names: names of the resource to remove. @return: a list of locks which we removed; the list is always @@ -1227,10 +1239,12 @@ class GanetiLockManager: def acquire(self, level, names, timeout=None, shared=0): """Acquire a set of resource locks, at the same level. - @param level: the level at which the locks shall be acquired; - it must be a member of LEVELS. + @type level: member of locking.LEVELS + @param level: the level at which the locks shall be acquired + @type names: list of strings (or string) @param names: the names of the locks which shall be acquired (special lock names, or instance/node names) + @type shared: integer (0/1) used as a boolean @param shared: whether to acquire in shared mode; by default an exclusive lock will be acquired @type timeout: float @@ -1261,8 +1275,9 @@ class GanetiLockManager: You must have acquired the locks, either in shared or in exclusive mode, before releasing them. - @param level: the level at which the locks shall be released; - it must be a member of LEVELS + @type level: member of locking.LEVELS + @param level: the level at which the locks shall be released + @type names: list of strings, or None @param names: the names of the locks which shall be released (defaults to all the locks acquired at that level) @@ -1281,10 +1296,13 @@ class GanetiLockManager: def add(self, level, names, acquired=0, shared=0): """Add locks at the specified level. - @param level: the level at which the locks shall be added; - it must be a member of LEVELS_MOD. + @type level: member of locking.LEVELS_MOD + @param level: the level at which the locks shall be added + @type names: list of strings @param names: names of the locks to acquire + @type acquired: integer (0/1) used as a boolean @param acquired: whether to acquire the newly added locks + @type shared: integer (0/1) used as a boolean @param shared: whether the acquisition will be shared """ @@ -1301,8 +1319,9 @@ class GanetiLockManager: You must either already own the locks you are trying to remove exclusively or not own any lock at an upper level. - @param level: the level at which the locks shall be removed; - it must be a member of LEVELS_MOD + @type level: member of locking.LEVELS_MOD + @param level: the level at which the locks shall be removed + @type names: list of strings @param names: the names of the locks which shall be removed (special lock names, or instance/node names)