()
| 146 | * same stale lock, only one create succeeds (the other reads the winner). |
| 147 | */ |
| 148 | export async function tryAcquireComputerUseLock(): Promise<AcquireResult> { |
| 149 | const sessionId = getSessionId() |
| 150 | const lock: ComputerUseLock = { |
| 151 | sessionId, |
| 152 | pid: process.pid, |
| 153 | acquiredAt: Date.now(), |
| 154 | } |
| 155 | |
| 156 | await mkdir(getClaudeConfigHomeDir(), { recursive: true }) |
| 157 | |
| 158 | // Fresh acquisition. |
| 159 | if (await tryCreateExclusive(lock)) { |
| 160 | registerLockCleanup() |
| 161 | return FRESH |
| 162 | } |
| 163 | |
| 164 | const existing = await readLock() |
| 165 | |
| 166 | // Corrupt/unparseable — treat as stale (can't extract a blocking ID). |
| 167 | if (!existing) { |
| 168 | await unlink(getLockPath()).catch(() => {}) |
| 169 | if (await tryCreateExclusive(lock)) { |
| 170 | registerLockCleanup() |
| 171 | return FRESH |
| 172 | } |
| 173 | return { kind: 'blocked', by: (await readLock())?.sessionId ?? 'unknown' } |
| 174 | } |
| 175 | |
| 176 | // Already held by this session. |
| 177 | if (existing.sessionId === sessionId) return REENTRANT |
| 178 | |
| 179 | // Another live session holds it — blocked. |
| 180 | if (isProcessRunning(existing.pid)) { |
| 181 | return { kind: 'blocked', by: existing.sessionId } |
| 182 | } |
| 183 | |
| 184 | // Stale lock — recover. Unlink then retry the exclusive create. |
| 185 | // If another session is also recovering, one EEXISTs and reads the winner. |
| 186 | logForDebugging( |
| 187 | `Recovering stale computer-use lock from session ${existing.sessionId} (PID ${existing.pid})`, |
| 188 | ) |
| 189 | await unlink(getLockPath()).catch(() => {}) |
| 190 | if (await tryCreateExclusive(lock)) { |
| 191 | registerLockCleanup() |
| 192 | return FRESH |
| 193 | } |
| 194 | return { kind: 'blocked', by: (await readLock())?.sessionId ?? 'unknown' } |
| 195 | } |
| 196 | |
| 197 | /** |
| 198 | * Release the computer-use lock if the current session owns it. Returns |
no test coverage detected