aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2021-03-07 05:48:41 -0800
committerZac Medico <zmedico@gentoo.org>2021-03-07 06:02:40 -0800
commit425aa9fb43e948e900478be3f47b799c0da6820f (patch)
tree794375462715d88721fc003df199d8bb7176d8de
parentdblink: add _format_contents_line method (diff)
downloadportage-425aa9fb43e948e900478be3f47b799c0da6820f.tar.gz
portage-425aa9fb43e948e900478be3f47b799c0da6820f.tar.bz2
portage-425aa9fb43e948e900478be3f47b799c0da6820f.zip
_test_lock_fn: use _lock_manager and call unlock
Signed-off-by: Zac Medico <zmedico@gentoo.org>
-rw-r--r--lib/portage/locks.py59
1 files changed, 30 insertions, 29 deletions
diff --git a/lib/portage/locks.py b/lib/portage/locks.py
index 4d0eede50..ddce72f62 100644
--- a/lib/portage/locks.py
+++ b/lib/portage/locks.py
@@ -35,6 +35,28 @@ _quiet = False
_lock_fn = None
+_open_fds = {}
+_open_inodes = {}
+
+class _lock_manager:
+ __slots__ = ('fd', 'inode_key')
+ def __init__(self, fd, fstat_result, path):
+ self.fd = fd
+ self.inode_key = (fstat_result.st_dev, fstat_result.st_ino)
+ if self.inode_key in _open_inodes:
+ # This means that the lock is already held by the current
+ # process, so the caller will have to try again. This case
+ # is encountered with the default fcntl.lockf function, and
+ # with the alternative fcntl.flock function TryAgain is
+ # raised earlier.
+ os.close(fd)
+ raise TryAgain(path)
+ _open_fds[fd] = self
+ _open_inodes[self.inode_key] = self
+ def close(self):
+ os.close(self.fd)
+ del _open_fds[self.fd]
+ del _open_inodes[self.inode_key]
def _get_lock_fn():
@@ -47,8 +69,8 @@ def _get_lock_fn():
return _lock_fn
if _test_lock_fn(
- lambda path, fd, flags: functools.partial(
- unlockfile, (path, fcntl.lockf(fd, flags), flags, fcntl.lockf)
+ lambda path, fd, flags: fcntl.lockf(fd, flags) and functools.partial(
+ unlockfile, (path, fd, flags, fcntl.lockf)
)
):
_lock_fn = fcntl.lockf
@@ -70,16 +92,19 @@ def _test_lock_fn(lock_fn: typing.Callable[[str, int, int], typing.Callable[[],
# Parent process holds lock, as expected.
sys.exit(0)
+
# Something went wrong.
sys.exit(1)
fd, lock_path = tempfile.mkstemp()
+ unlock_fn = None
try:
try:
- lock_fn(lock_path, fd, fcntl.LOCK_EX)
+ unlock_fn = lock_fn(lock_path, fd, fcntl.LOCK_EX)
except (TryAgain, EnvironmentError):
pass
else:
+ _lock_manager(fd, os.fstat(fd), lock_path)
proc = multiprocessing.Process(target=_test_lock,
args=(fd, lock_path))
proc.start()
@@ -88,35 +113,11 @@ def _test_lock_fn(lock_fn: typing.Callable[[str, int, int], typing.Callable[[],
# the test passed
return True
finally:
- os.close(fd)
- os.unlink(lock_path)
+ if unlock_fn is not None:
+ unlock_fn()
return False
-_open_fds = {}
-_open_inodes = {}
-
-class _lock_manager:
- __slots__ = ('fd', 'inode_key')
- def __init__(self, fd, fstat_result, path):
- self.fd = fd
- self.inode_key = (fstat_result.st_dev, fstat_result.st_ino)
- if self.inode_key in _open_inodes:
- # This means that the lock is already held by the current
- # process, so the caller will have to try again. This case
- # is encountered with the default fcntl.lockf function, and
- # with the alternative fcntl.flock function TryAgain is
- # raised earlier.
- os.close(fd)
- raise TryAgain(path)
- _open_fds[fd] = self
- _open_inodes[self.inode_key] = self
- def close(self):
- os.close(self.fd)
- del _open_fds[self.fd]
- del _open_inodes[self.inode_key]
-
-
def _close_fds():
"""
This is intended to be called after a fork, in order to close file