aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2025-08-26 11:20:27 +0200
committerJussi Pakkanen <jussi.pakkanen@mailbox.org>2025-08-29 12:17:51 +0300
commitfb6db4070e7a40ca701914fab6e8c31f65da89c4 (patch)
tree5302f387fc5a15d5466692e30ae6e6285e3842fa
parent191a315586d2202f76cddc27f7c3579eafbbdce1 (diff)
downloadmeson-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.py5
-rw-r--r--mesonbuild/utils/posix.py11
-rw-r--r--mesonbuild/utils/win32.py11
-rw-r--r--mesonbuild/wrap/wrap.py2
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.')