fix: isLockProcessAlive should return true for own PID (#2642)
The self-PID guard in isLockProcessAlive returned false for process.pid, treating the current process as dead. This caused the doctor to delete auto.lock and .gsd.lock/ during live auto-mode sessions (via postUnitPreVerification), breaking the session lock and silently stopping auto-mode. The guard was originally added for startAuto() where a matching PID could mean a recycled PID from a prior crash. But startAuto already has its own `crashLock.pid !== process.pid` check before calling isLockProcessAlive, so the function-level guard was redundant there and harmful everywhere else. Change `pid === process.pid` to return true (alive) instead of false. Closes #2470
This commit is contained in:
parent
6f3275ff59
commit
14e5264d52
3 changed files with 13 additions and 7 deletions
|
|
@ -76,12 +76,16 @@ export function readCrashLock(basePath: string): LockData | null {
|
|||
/**
|
||||
* Check whether the process that wrote the lock is still running.
|
||||
* Uses `process.kill(pid, 0)` which sends no signal but checks liveness.
|
||||
* Returns false if the PID matches our own (recycled PID from a prior run).
|
||||
* Returns true if the PID matches our own — we are the lock holder (#2470).
|
||||
*/
|
||||
export function isLockProcessAlive(lock: LockData): boolean {
|
||||
const pid = lock.pid;
|
||||
if (!Number.isInteger(pid) || pid <= 0) return false;
|
||||
if (pid === process.pid) return false;
|
||||
// Our own PID means WE hold this lock — we are alive. (#2470)
|
||||
// Callers that need to distinguish "our lock" from "someone else's lock"
|
||||
// (e.g. startAuto checking for a prior crashed session with a recycled PID)
|
||||
// already guard with `crashLock.pid !== process.pid` before calling us.
|
||||
if (pid === process.pid) return true;
|
||||
try {
|
||||
process.kill(pid, 0);
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ test("isLockProcessAlive returns false for dead PID", () => {
|
|||
assert.equal(isLockProcessAlive(lock), false, "dead PID should return false");
|
||||
});
|
||||
|
||||
test("isLockProcessAlive returns false for own PID (recycled)", () => {
|
||||
test("#2470: isLockProcessAlive returns true for own PID (we hold the lock)", () => {
|
||||
const lock = {
|
||||
pid: process.pid,
|
||||
startedAt: new Date().toISOString(),
|
||||
|
|
@ -148,7 +148,7 @@ test("isLockProcessAlive returns false for own PID (recycled)", () => {
|
|||
unitId: "M001/S01/T01",
|
||||
unitStartedAt: new Date().toISOString(),
|
||||
};
|
||||
assert.equal(isLockProcessAlive(lock), false, "own PID should return false (recycled)");
|
||||
assert.equal(isLockProcessAlive(lock), true, "own PID means we are alive — not stale (#2470)");
|
||||
});
|
||||
|
||||
test("isLockProcessAlive returns false for invalid PID", () => {
|
||||
|
|
|
|||
|
|
@ -68,8 +68,10 @@ test("clearLock is safe when no lock exists", (t) => {
|
|||
|
||||
// ─── isLockProcessAlive ──────────────────────────────────────────────────
|
||||
|
||||
test("isLockProcessAlive returns true for current process (different pid)", () => {
|
||||
// Our own PID is explicitly excluded (recycled PID guard)
|
||||
test("#2470: isLockProcessAlive returns true for own PID (we hold the lock)", () => {
|
||||
// Own PID means we ARE the lock holder — alive, not stale. (#2470)
|
||||
// Callers that need recycled-PID detection (e.g. startAuto) already
|
||||
// guard with `crashLock.pid !== process.pid` before calling us.
|
||||
const lock: LockData = {
|
||||
pid: process.pid,
|
||||
startedAt: new Date().toISOString(),
|
||||
|
|
@ -77,7 +79,7 @@ test("isLockProcessAlive returns true for current process (different pid)", () =
|
|||
unitId: "M001/S01/T01",
|
||||
unitStartedAt: new Date().toISOString(),
|
||||
};
|
||||
assert.equal(isLockProcessAlive(lock), false, "own PID should return false");
|
||||
assert.equal(isLockProcessAlive(lock), true, "own PID should return true — we are alive");
|
||||
});
|
||||
|
||||
test("isLockProcessAlive returns false for dead PID", () => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue