Files
codegraph/__tests__
Colby MchenryandClaude Opus 5.5 29ce0149cf fix(lock): only one process takes over a stale write lock (#3056)
Issue #2979: FileLock.acquire() read the lock file, saw a dead PID,
unlinked the file and created its own with an exclusive create. Two
processes that read the same dead PID could both succeed: the first one
replaced the stale lock, then the second one, acting on what it had read
a moment earlier, unlinked the first one's live lock and created its own.
Both returned from acquire() and wrote to the index as its only writer.
The same steal happened in two narrower ways: a lock file read in the
instant between its exclusive create and the write of its PID was empty,
so it counted as stale, and a PID the process may not signal (EPERM:
another user's process, or an elevated one on Windows) counted as dead.

The fix keeps the lock file and its format (a bare PID) and changes how
it is taken:
- A free lock costs one create, as before. The lock file is created with
  its PID already in it: a private file hard-linked into place, which
  fails if the lock exists. Where hard links are missing it falls back
  to the exclusive create, and an empty lock younger than 10 s counts as
  held, since its creator is still writing its PID.
- A stale lock (dead PID, malformed, or empty and old) is replaced only
  by the process holding <lock>.break, itself a FileLock, after reading
  the lock again there, the way Mercurial breaks its locks. A break lock
  a crashed process left is broken the same way, one level up, at most
  three levels.
- EPERM from a signal-0 probe means the holder is alive.

Validation: __tests__/filelock-stale-takeover.test.ts runs two real
processes with a barrier: the slow one stops right after reading the
dead PID and resumes only once the other holds the lock. On main both
held it, 5 runs of 5; with the fix the slow one is refused and the lock
stays the holder's. The other cases cover the slow one getting in once
the lock is free, a live and a dead break lock, the empty-lock window,
EPERM (mocked, and for real on Windows with the System process), and no
leftover files.

Fixes #2979

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 10:40:44 +00:00
..