Skip to content

Lock during experimental editable.rebuild #968

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 94 additions & 34 deletions src/scikit_build_core/resources/_editable_redirect.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,59 @@
return __all__


class FileLockIfUnix:
def __init__(self, lock_file: str) -> None:
self.lock_file = lock_file
self.lock_file_fd: int | None = None

Check warning on line 28 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L27-L28

Added lines #L27 - L28 were not covered by tests

def acquire(self) -> None:
# Based on filelock.BaseFileLock.acquire and filelock.UnixFileLock._acquire
try:
import fcntl
except ImportError:
return
import contextlib
import time

Check warning on line 37 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L32-L37

Added lines #L32 - L37 were not covered by tests

poll_interval = 0.05
log_interval = 60
last_log = time.perf_counter()

Check warning on line 41 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L39-L41

Added lines #L39 - L41 were not covered by tests

while True:
os.makedirs(os.path.dirname(self.lock_file), exist_ok=True)
open_flags = os.O_RDWR | os.O_TRUNC
if not os.path.exists(self.lock_file):
open_flags |= os.O_CREAT

Check warning on line 47 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L43-L47

Added lines #L43 - L47 were not covered by tests

fd = os.open(self.lock_file, open_flags, 0o644)
with contextlib.suppress(PermissionError): # Lock is not owned by this UID
os.fchmod(fd, 0o644)
try:
fcntl.flock(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
except OSError:
os.close(fd)

Check warning on line 55 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L49-L55

Added lines #L49 - L55 were not covered by tests
else:
self.lock_file_fd = fd
return

Check warning on line 58 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L57-L58

Added lines #L57 - L58 were not covered by tests

now = time.perf_counter()
if now - last_log > log_interval:
last_log = now

Check warning on line 62 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L60-L62

Added lines #L60 - L62 were not covered by tests
print(f"Still waiting to acquire lock {self.lock_file}...") # noqa: T201

time.sleep(poll_interval)

Check warning on line 65 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L65

Added line #L65 was not covered by tests

def release(self) -> None:
try:
import fcntl
except ImportError:
return

Check warning on line 71 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L68-L71

Added lines #L68 - L71 were not covered by tests

assert isinstance(self.lock_file_fd, int)
fcntl.flock(self.lock_file_fd, fcntl.LOCK_UN)
os.close(self.lock_file_fd)

Check warning on line 75 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L73-L75

Added lines #L73 - L75 were not covered by tests


class ScikitBuildRedirectingFinder(importlib.abc.MetaPathFinder):
def __init__(
self,
Expand Down Expand Up @@ -128,42 +181,49 @@
if verbose:
print(f"Running cmake --build & --install in {self.path}") # noqa: T201

result = subprocess.run(
["cmake", "--build", ".", *self.build_options],
cwd=self.path,
stdout=sys.stderr if verbose else subprocess.PIPE,
env=env,
check=False,
text=True,
)
if result.returncode and verbose:
print( # noqa: T201
f"ERROR: {result.stdout}",
file=sys.stderr,
lock = FileLockIfUnix(os.path.join(self.path, "editable_rebuild.lock"))

Check warning on line 184 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L184

Added line #L184 was not covered by tests

try:
lock.acquire()

Check warning on line 187 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L186-L187

Added lines #L186 - L187 were not covered by tests

result = subprocess.run(

Check warning on line 189 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L189

Added line #L189 was not covered by tests
["cmake", "--build", ".", *self.build_options],
cwd=self.path,
stdout=sys.stderr if verbose else subprocess.PIPE,
env=env,
check=False,
text=True,
)
result.check_returncode()

result = subprocess.run(
[
"cmake",
"--install",
".",
"--prefix",
self.install_dir,
*self.install_options,
],
cwd=self.path,
stdout=sys.stderr if verbose else subprocess.PIPE,
env=env,
check=False,
text=True,
)
if result.returncode and verbose:
print( # noqa: T201
f"ERROR: {result.stdout}",
file=sys.stderr,
if result.returncode and verbose:
print( # noqa: T201

Check warning on line 198 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L197-L198

Added lines #L197 - L198 were not covered by tests
f"ERROR: {result.stdout}",
file=sys.stderr,
)
result.check_returncode()

Check warning on line 202 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L202

Added line #L202 was not covered by tests

result = subprocess.run(

Check warning on line 204 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L204

Added line #L204 was not covered by tests
[
"cmake",
"--install",
".",
"--prefix",
self.install_dir,
*self.install_options,
],
cwd=self.path,
stdout=sys.stderr if verbose else subprocess.PIPE,
env=env,
check=False,
text=True,
)
result.check_returncode()
if result.returncode and verbose:
print( # noqa: T201

Check warning on line 220 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L219-L220

Added lines #L219 - L220 were not covered by tests
f"ERROR: {result.stdout}",
file=sys.stderr,
)
result.check_returncode()

Check warning on line 224 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L224

Added line #L224 was not covered by tests
finally:
lock.release()

Check warning on line 226 in src/scikit_build_core/resources/_editable_redirect.py

View check run for this annotation

Codecov / codecov/patch

src/scikit_build_core/resources/_editable_redirect.py#L226

Added line #L226 was not covered by tests


def install(
Expand Down
Loading