from ganeti import utils
+def ssynchronized(lock, shared=0):
+ """Shared Synchronization decorator.
+
+ Calls the function holding the given lock, either in exclusive or shared
+ mode. It requires the passed lock to be a SharedLock (or support its
+ semantics).
+
+ """
+ def wrap(fn):
+ def sync_function(*args, **kwargs):
+ lock.acquire(shared=shared)
+ try:
+ return fn(*args, **kwargs)
+ finally:
+ lock.release()
+ return sync_function
+ return wrap
+
+
class SharedLock:
"""Implements a shared lock.
Args:
shared: whether to acquire in shared mode. By default an exclusive lock
will be acquired.
- blocking: whether to block while trying to acquire or to operate in try-lock mode.
- this locking mode is not supported yet.
+ blocking: whether to block while trying to acquire or to operate in
+ try-lock mode. this locking mode is not supported yet.
"""
if not blocking:
self.__npass_shr = self.__nwait_shr
self.__turn_shr.notifyAll()
elif self.__nwait_exc > 0:
- self.__turn_exc.notify()
+ self.__turn_exc.notify()
elif self.__is_sharer():
self.__shr.remove(threading.currentThread())
# If there are shared holders waiting (and not just scheduled to pass)
# there *must* be an exclusive holder waiting as well; otherwise what
# were they waiting for?
- assert (self.__nwait_exc > 0 or self.__npass_shr > 0 or
- self.__nwait_shr == 0), \
+ assert (self.__nwait_exc > 0 or self.__npass_shr == self.__nwait_shr), \
"Lock sharers waiting while no exclusive is queueing"
# If there are no more shared holders either in or scheduled to pass,
(special lock names, or instance/node names)
shared: whether to acquire in shared mode. By default an exclusive lock
will be acquired.
- blocking: whether to block while trying to acquire or to operate in try-lock mode.
- this locking mode is not supported yet.
+ blocking: whether to block while trying to acquire or to operate in
+ try-lock mode. this locking mode is not supported yet.
Returns:
True: when all the locks are successfully acquired
# just one of them be the already wrong
for lname in names:
try:
- lock = self.__lockdict[lname] # raises KeyError if the lock is not there
+ lock = self.__lockdict[lname] # raises KeyError if lock is not there
acquire_list.append((lname, lock))
except (KeyError):
if self.__lock._is_owned():
# - at levels LEVEL_NODE and LEVEL_INSTANCE reside node and instance locks.
# If you need more than one node, or more than one instance, acquire them at
# the same time.
-# - level LEVEL_CONFIG contains the configuration lock, which you must acquire
-# before reading or changing the config file.
LEVEL_CLUSTER = 0
-LEVEL_NODE = 1
-LEVEL_INSTANCE = 2
-LEVEL_CONFIG = 3
+LEVEL_INSTANCE = 1
+LEVEL_NODE = 2
LEVELS = [LEVEL_CLUSTER,
- LEVEL_NODE,
LEVEL_INSTANCE,
- LEVEL_CONFIG]
+ LEVEL_NODE]
# Lock levels which are modifiable
LEVELS_MOD = [LEVEL_NODE, LEVEL_INSTANCE]
-# Constant for the big ganeti lock and config lock
+# Constant for the big ganeti lock
BGL = 'BGL'
-CONFIG = 'config'
class GanetiLockManager:
def __init__(self, nodes=None, instances=None):
"""Constructs a new GanetiLockManager object.
- There should be only a
- GanetiLockManager object at any time, so this function raises an error if this
- is not the case.
+ There should be only a GanetiLockManager object at any time, so this
+ function raises an error if this is not the case.
Args:
nodes: list of node names
LEVEL_CLUSTER: LockSet([BGL]),
LEVEL_NODE: LockSet(nodes),
LEVEL_INSTANCE: LockSet(instances),
- LEVEL_CONFIG: LockSet([CONFIG]),
}
def _names(self, level):
(special lock names, or instance/node names)
shared: whether to acquire in shared mode. By default an exclusive lock
will be acquired.
- blocking: whether to block while trying to acquire or to operate in try-lock mode.
- this locking mode is not supported yet.
+ blocking: whether to block while trying to acquire or to operate in
+ try-lock mode. this locking mode is not supported yet.
"""
assert level in LEVELS, "Invalid locking level %s" % level
"You must own the Big Ganeti Lock before acquiring any other")
# Check we don't own locks at the same or upper levels.
- assert not self._upper_owned(level), ("Cannot acquire locks at a level"
+ assert not self._upper_owned(level), ("Cannot acquire locks at a level"
" while owning some at a greater one")
# Acquire the locks in the set.