From fadb712f573bcd6d70b247cd349c66285a98b36f Mon Sep 17 00:00:00 2001 From: Joshua Harlow Date: Fri, 31 Jan 2014 19:26:02 -0800 Subject: [PATCH] Update oslo.lock from incubator commit 3c125e66d183 Note that this is not the full module but only the pieces that taskflow uses. This is to avoid bringing in bundled libraries that the full module would bring in (oslo.config being the primary problematic case). Change-Id: I63b171c69f5d415d55d8c0857521e69d905aa85f --- taskflow/utils/lock_utils.py | 57 ++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/taskflow/utils/lock_utils.py b/taskflow/utils/lock_utils.py index 46d78230..7f227983 100644 --- a/taskflow/utils/lock_utils.py +++ b/taskflow/utils/lock_utils.py @@ -30,7 +30,6 @@ import time from taskflow.utils import misc LOG = logging.getLogger(__name__) -WAIT_TIME = 0.01 def locked(*args, **kwargs): @@ -127,23 +126,18 @@ class _InterProcessLock(object): """ def __init__(self, name): - self._lockfile = None - self._fname = name - - @property - def path(self): - return self._fname - - def release(self): - try: - self.unlock() - self._lockfile.close() - except IOError: - LOG.exception("Could not release the acquired lock `%s`", - self.path) + self.lockfile = None + self.fname = name def acquire(self): - self._lockfile = open(self.path, 'w') + basedir = os.path.dirname(self.fname) + + if not os.path.exists(basedir): + misc.ensure_tree(basedir) + LOG.info('Created lock path: %s', basedir) + + self.lockfile = open(self.fname, 'w') + while True: try: # Using non-blocking locks since green threads are not @@ -151,17 +145,36 @@ class _InterProcessLock(object): # Also upon reading the MSDN docs for locking(), it seems # to have a laughable 10 attempts "blocking" mechanism. self.trylock() + LOG.debug('Got file lock "%s"', self.fname) return True except IOError as e: if e.errno in (errno.EACCES, errno.EAGAIN): - time.sleep(WAIT_TIME) + # external locks synchronise things like iptables + # updates - give it some time to prevent busy spinning + time.sleep(0.01) else: - raise + raise threading.ThreadError("Unable to acquire lock on" + " `%(filename)s` due to" + " %(exception)s" % + { + 'filename': self.fname, + 'exception': e, + }) def __enter__(self): self.acquire() return self + def release(self): + try: + self.unlock() + self.lockfile.close() + # This is fixed in: https://review.openstack.org/70506 + LOG.debug('Released file lock "%s"', self.fname) + except IOError: + LOG.exception("Could not release the acquired lock `%s`", + self.fname) + def __exit__(self, exc_type, exc_val, exc_tb): self.release() @@ -174,18 +187,18 @@ class _InterProcessLock(object): class _WindowsLock(_InterProcessLock): def trylock(self): - msvcrt.locking(self._lockfile.fileno(), msvcrt.LK_NBLCK, 1) + msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_NBLCK, 1) def unlock(self): - msvcrt.locking(self._lockfile.fileno(), msvcrt.LK_UNLCK, 1) + msvcrt.locking(self.lockfile.fileno(), msvcrt.LK_UNLCK, 1) class _PosixLock(_InterProcessLock): def trylock(self): - fcntl.lockf(self._lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB) + fcntl.lockf(self.lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB) def unlock(self): - fcntl.lockf(self._lockfile, fcntl.LOCK_UN) + fcntl.lockf(self.lockfile, fcntl.LOCK_UN) if os.name == 'nt':