Skip to content

Commit

Permalink
wrap: Lock subproject directory when downloading wraps
Browse files Browse the repository at this point in the history
To avoid raceconditions, where one instance of meson currently downloads
a subproject defined in a wrapfile, while another either
  a. starts the download itself too
  b. attemts to evaluate the partially downloaded subproject
wraplock introduces a lockfile, which should prevent simultaneous access
of subprojects by wrap between different instances of meson.
  • Loading branch information
sp1ritCS committed Nov 1, 2024
1 parent 5e2e39d commit 0dbee14
Showing 1 changed file with 11 additions and 2 deletions.
13 changes: 11 additions & 2 deletions mesonbuild/wrap/wrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

from . import WrapMode
from .. import coredata
from ..mesonlib import quiet_git, GIT, ProgressBar, MesonException, windows_proof_rmtree, Popen_safe
from ..mesonlib import (
DirectoryLock, DirectoryLockAction, quiet_git, GIT, ProgressBar, MesonException,
windows_proof_rmtree, Popen_safe
)
from ..interpreterbase import FeatureNew
from ..interpreterbase import SubProject
from .. import mesonlib
Expand Down Expand Up @@ -432,7 +435,7 @@ def find_program_provider(self, names: T.List[str]) -> T.Optional[str]:
return wrap_name
return None

def resolve(self, packagename: str, force_method: T.Optional[Method] = None) -> T.Tuple[str, Method]:
def _resolve(self, packagename: str, force_method: T.Optional[Method] = None) -> T.Tuple[str, Method]:
wrap = self.wraps.get(packagename)
if wrap is None:
wrap = self.get_from_wrapdb(packagename)
Expand Down Expand Up @@ -530,6 +533,12 @@ def has_buildfile() -> bool:
self.wrap.update_hash_cache(self.dirname)
return rel_path, method

def resolve(self, packagename: str, force_method: T.Optional[Method] = None) -> T.Tuple[str, Method]:
with DirectoryLock(self.subdir_root, '.wraplock',
DirectoryLockAction.WAIT,
'Failed to lock subprojects directory'):
return self._resolve(packagename, force_method)

def check_can_download(self) -> None:
# Don't download subproject data based on wrap file if requested.
# Git submodules are ok (see above)!
Expand Down

0 comments on commit 0dbee14

Please sign in to comment.