X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/7260cfbe90e7bf0a30b296a8196618c8558d08b9..cc0d88e95afa0be2cf4aa563904016c5a067d4cd:/lib/locking.py?ds=inline diff --git a/lib/locking.py b/lib/locking.py index 6ba74f2..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 """ @@ -775,7 +780,9 @@ class LockSet: def _release_and_delete_owned(self): """Release and delete all resources owned by the current thread""" for lname in self._list_owned(): - self.__lockdict[lname].release() + lock = self.__lockdict[lname] + if lock._is_owned(): + lock.release() self._del_owned(name=lname) def __names(self): @@ -809,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 @@ -839,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) @@ -889,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 @@ -902,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() @@ -966,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). @@ -999,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? """ @@ -1060,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 @@ -1225,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 @@ -1259,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) @@ -1279,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 """ @@ -1299,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)