Skip to content

Fix race condition when two processes build the same core image - #5

Open
kisp wants to merge 2 commits into
masterfrom
feature/3-does-not-work-if-two-processes-attempt-to-build-the-same-core-image-at-the-same-time
Open

Fix race condition when two processes build the same core image#5
kisp wants to merge 2 commits into
masterfrom
feature/3-does-not-work-if-two-processes-attempt-to-build-the-same-core-image-at-the-same-time

Conversation

@kisp

@kisp kisp commented May 22, 2026

Copy link
Copy Markdown
Owner

Fixes #3

What was wrong

ensureImage checks doesFileExist, gets False, and calls makeImage. If two processes do this simultaneously they both pipe a Lisp script ending in (sb-ext:save-lisp-and-die "<imagePath>") to separate SBCL processes. Both write to the same path concurrently, corrupting the core file.

Fix

Each call to makeImage now writes to a private temp file:

<imagePath>.tmp.<pid>

On success, POSIX rename(2) moves it atomically to imagePath. rename on Linux replaces the destination if it already exists, so if two processes race to rename, one silently overwrites the other with an equivalent image and both callers proceed normally.

On build failure the temp file is removed (best-effort via catchIOError).

Changes

  • sbclScript gains a tmpPath parameter; save-lisp-and-die targets tmpPath while ensure-directories-exist still uses imagePath (same directory, ensures the cache dir exists)
  • makeImage calls getProcessID to form tmpPath, passes it to sbclScript, then renames on success or cleans up on failure
  • New imports: getProcessID, System.Posix.Files.rename, catchIOError

Test plan

  • nix build passes (binary produced)
  • HOME="$(mktemp -d)" nix run .#test to run the integration suite

kisp and others added 2 commits May 22, 2026 15:16
…build the same core image at the same time

#3
Two concurrent sbcl-wrap processes building the same core image would
both pipe a save-lisp-and-die call writing to the same path, corrupting
the file.

Fix: each process writes to <imagePath>.tmp.<pid>, then calls
POSIX rename(2) which atomically replaces the destination. If two
processes race to rename, one silently overwrites the other with an
equivalent image and both callers proceed normally.

On build failure the tmp file is removed (best-effort).

Closes #3

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Does not work if two processes attempt to build the same core image at the same time

1 participant