summaryrefslogtreecommitdiff
path: root/pycadf/openstack/common/lockutils.py
diff options
context:
space:
mode:
Diffstat (limited to 'pycadf/openstack/common/lockutils.py')
-rw-r--r--pycadf/openstack/common/lockutils.py92
1 files changed, 20 insertions, 72 deletions
diff --git a/pycadf/openstack/common/lockutils.py b/pycadf/openstack/common/lockutils.py
index 7bbb1d2..9814891 100644
--- a/pycadf/openstack/common/lockutils.py
+++ b/pycadf/openstack/common/lockutils.py
@@ -15,8 +15,8 @@
import contextlib
import errno
-import fcntl
import functools
+import logging
import os
import shutil
import subprocess
@@ -29,8 +29,7 @@ import weakref
from oslo.config import cfg
from pycadf.openstack.common import fileutils
-from pycadf.openstack.common.gettextutils import _, _LE, _LI
-from pycadf.openstack.common import log as logging
+from pycadf.openstack.common._i18n import _, _LE, _LI
LOG = logging.getLogger(__name__)
@@ -102,10 +101,8 @@ class _FileLock(object):
raise threading.ThreadError(_("Unable to acquire lock on"
" `%(filename)s` due to"
" %(exception)s") %
- {
- 'filename': self.fname,
- 'exception': e,
- })
+ {'filename': self.fname,
+ 'exception': e})
def __enter__(self):
self.acquire()
@@ -149,56 +146,12 @@ class _FcntlLock(_FileLock):
fcntl.lockf(self.lockfile, fcntl.LOCK_UN)
-class _PosixLock(object):
- def __init__(self, name):
- # Hash the name because it's not valid to have POSIX semaphore
- # names with things like / in them. Then use base64 to encode
- # the digest() instead taking the hexdigest() because the
- # result is shorter and most systems can't have shm sempahore
- # names longer than 31 characters.
- h = hashlib.sha1()
- h.update(name.encode('ascii'))
- self.name = str((b'/' + base64.urlsafe_b64encode(
- h.digest())).decode('ascii'))
-
- def acquire(self, timeout=None):
- self.semaphore = posix_ipc.Semaphore(self.name,
- flags=posix_ipc.O_CREAT,
- initial_value=1)
- self.semaphore.acquire(timeout)
- return self
-
- def __enter__(self):
- self.acquire()
- return self
-
- def release(self):
- self.semaphore.release()
- self.semaphore.close()
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.release()
-
- def exists(self):
- try:
- semaphore = posix_ipc.Semaphore(self.name)
- except posix_ipc.ExistentialError:
- return False
- else:
- semaphore.close()
- return True
-
-
if os.name == 'nt':
import msvcrt
InterProcessLock = _WindowsLock
- FileLock = _WindowsLock
else:
- import base64
- import hashlib
- import posix_ipc
- InterProcessLock = _PosixLock
- FileLock = _FcntlLock
+ import fcntl
+ InterProcessLock = _FcntlLock
_semaphores = weakref.WeakValueDictionary()
_semaphores_lock = threading.Lock()
@@ -215,11 +168,7 @@ def _get_lock_path(name, lock_file_prefix, lock_path=None):
local_lock_path = lock_path or CONF.lock_path
if not local_lock_path:
- # NOTE(bnemec): Create a fake lock path for posix locks so we don't
- # unnecessarily raise the RequiredOptError below.
- if InterProcessLock is not _PosixLock:
- raise cfg.RequiredOptError('lock_path')
- local_lock_path = 'posixlock:/'
+ raise cfg.RequiredOptError('lock_path')
return os.path.join(local_lock_path, name)
@@ -230,16 +179,11 @@ def external_lock(name, lock_file_prefix=None, lock_path=None):
lock_file_path = _get_lock_path(name, lock_file_prefix, lock_path)
- # NOTE(bnemec): If an explicit lock_path was passed to us then it
- # means the caller is relying on file-based locking behavior, so
- # we can't use posix locks for those calls.
- if lock_path:
- return FileLock(lock_file_path)
return InterProcessLock(lock_file_path)
def remove_external_lock_file(name, lock_file_prefix=None):
- """Remove a external lock file when it's not used anymore
+ """Remove an external lock file when it's not used anymore
This will be helpful when we have a lot of lock files
"""
with internal_lock(name):
@@ -255,11 +199,12 @@ def internal_lock(name):
with _semaphores_lock:
try:
sem = _semaphores[name]
+ LOG.debug('Using existing semaphore "%s"', name)
except KeyError:
sem = threading.Semaphore()
_semaphores[name] = sem
+ LOG.debug('Created new semaphore "%s"', name)
- LOG.debug('Got semaphore "%(lock)s"', {'lock': name})
return sem
@@ -281,13 +226,16 @@ def lock(name, lock_file_prefix=None, external=False, lock_path=None):
"""
int_lock = internal_lock(name)
with int_lock:
- if external and not CONF.disable_process_locking:
- ext_lock = external_lock(name, lock_file_prefix, lock_path)
- with ext_lock:
- yield ext_lock
- else:
- yield int_lock
- LOG.debug('Released semaphore "%(lock)s"', {'lock': name})
+ LOG.debug('Acquired semaphore "%(lock)s"', {'lock': name})
+ try:
+ if external and not CONF.disable_process_locking:
+ ext_lock = external_lock(name, lock_file_prefix, lock_path)
+ with ext_lock:
+ yield ext_lock
+ else:
+ yield int_lock
+ finally:
+ LOG.debug('Releasing semaphore "%(lock)s"', {'lock': name})
def synchronized(name, lock_file_prefix=None, external=False, lock_path=None):