diff --git a/msal_extensions/cache_lock.py b/msal_extensions/cache_lock.py index 2a73f24..1adcb5d 100644 --- a/msal_extensions/cache_lock.py +++ b/msal_extensions/cache_lock.py @@ -12,17 +12,23 @@ class CrossPlatLock(object): """ def __init__(self, lockfile_path): self._lockpath = lockfile_path - self._fh = None + self._lock = portalocker.Lock( + lockfile_path, + mode='wb+', + # In posix systems, we HAVE to use LOCK_EX(exclusive lock) bitwise ORed + # with LOCK_NB(non-blocking) to avoid blocking on lock acquisition. + # More information here: + # https://docs.python.org/3/library/fcntl.html#fcntl.lockf + flags=portalocker.LOCK_EX | portalocker.LOCK_NB, + buffering=0) def __enter__(self): - pid = os.getpid() - - self._fh = open(self._lockpath, 'wb+', buffering=0) - portalocker.lock(self._fh, portalocker.LOCK_EX) - self._fh.write('{} {}'.format(pid, sys.argv[0]).encode('utf-8')) + file_handle = self._lock.__enter__() + file_handle.write('{} {}'.format(os.getpid(), sys.argv[0]).encode('utf-8')) + return file_handle def __exit__(self, *args): - self._fh.close() + self._lock.__exit__(*args) try: # Attempt to delete the lockfile. In either of the failure cases enumerated below, it is # likely that another process has raced this one and ended up clearing or locking the diff --git a/setup.py b/setup.py index ce2845c..4c742a7 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ package_data={'': ['LICENSE']}, install_requires=[ 'msal>=0.4.1,<2.0.0', - 'portalocker~=1.0', + 'portalocker~=1.6', ], tests_require=['pytest'], )