diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2025-08-26 11:20:27 +0200 |
---|---|---|
committer | Jussi Pakkanen <jussi.pakkanen@mailbox.org> | 2025-08-29 12:17:51 +0300 |
commit | fb6db4070e7a40ca701914fab6e8c31f65da89c4 (patch) | |
tree | 5302f387fc5a15d5466692e30ae6e6285e3842fa | |
parent | 191a315586d2202f76cddc27f7c3579eafbbdce1 (diff) | |
download | meson-fb6db4070e7a40ca701914fab6e8c31f65da89c4.zip meson-fb6db4070e7a40ca701914fab6e8c31f65da89c4.tar.gz meson-fb6db4070e7a40ca701914fab6e8c31f65da89c4.tar.bz2 |
utils: make .wraplock optional
.wraplock is nice to have, but prevents Meson from operating on a
read-only source directory.
If the source directory is read-only, there is no possible conflict
so in that case it is acceptable to return without any actual locking.
Fixes: #14948
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | mesonbuild/utils/platform.py | 5 | ||||
-rw-r--r-- | mesonbuild/utils/posix.py | 11 | ||||
-rw-r--r-- | mesonbuild/utils/win32.py | 11 | ||||
-rw-r--r-- | mesonbuild/wrap/wrap.py | 2 |
4 files changed, 25 insertions, 4 deletions
diff --git a/mesonbuild/utils/platform.py b/mesonbuild/utils/platform.py index 8fdfee6..f9eaa47 100644 --- a/mesonbuild/utils/platform.py +++ b/mesonbuild/utils/platform.py @@ -20,10 +20,13 @@ class DirectoryLockAction(enum.Enum): FAIL = 2 class DirectoryLockBase: - def __init__(self, directory: str, lockfile: str, action: DirectoryLockAction, err: str) -> None: + def __init__(self, directory: str, lockfile: str, action: DirectoryLockAction, err: str, + optional: bool = False) -> None: self.action = action self.err = err self.lockpath = os.path.join(directory, lockfile) + self.optional = optional + self.lockfile: T.Optional[T.TextIO] = None def __enter__(self) -> None: mlog.debug('Calling the no-op version of DirectoryLock') diff --git a/mesonbuild/utils/posix.py b/mesonbuild/utils/posix.py index a601dee..9dbc5c1 100644 --- a/mesonbuild/utils/posix.py +++ b/mesonbuild/utils/posix.py @@ -17,7 +17,16 @@ __all__ = ['DirectoryLock', 'DirectoryLockAction'] class DirectoryLock(DirectoryLockBase): def __enter__(self) -> None: - self.lockfile = open(self.lockpath, 'w+', encoding='utf-8') + try: + self.lockfile = open(self.lockpath, 'w+', encoding='utf-8') + except (FileNotFoundError, IsADirectoryError): + # For FileNotFoundError, there is nothing to lock. + # For IsADirectoryError, something is seriously wrong. + raise + except OSError: + if self.action == DirectoryLockAction.IGNORE or self.optional: + return + try: flags = fcntl.LOCK_EX if self.action != DirectoryLockAction.WAIT: diff --git a/mesonbuild/utils/win32.py b/mesonbuild/utils/win32.py index 22aea86..8f1a099 100644 --- a/mesonbuild/utils/win32.py +++ b/mesonbuild/utils/win32.py @@ -17,7 +17,16 @@ __all__ = ['DirectoryLock', 'DirectoryLockAction'] class DirectoryLock(DirectoryLockBase): def __enter__(self) -> None: - self.lockfile = open(self.lockpath, 'w+', encoding='utf-8') + try: + self.lockfile = open(self.lockpath, 'w+', encoding='utf-8') + except (FileNotFoundError, IsADirectoryError): + # For FileNotFoundError, there is nothing to lock. + # For IsADirectoryError, something is seriously wrong. + raise + except OSError: + if self.action == DirectoryLockAction.IGNORE or self.optional: + return + try: mode = msvcrt.LK_LOCK if self.action != DirectoryLockAction.WAIT: diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index 1cc2cee..f8ed5e0 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -588,7 +588,7 @@ class Resolver: try: with DirectoryLock(self.subdir_root, '.wraplock', DirectoryLockAction.WAIT, - 'Failed to lock subprojects directory'): + 'Failed to lock subprojects directory', optional=True): return self._resolve(packagename, force_method) except FileNotFoundError: raise WrapNotFoundException('Attempted to resolve subproject without subprojects directory present.') |