Skip to content

fix: name the processes holding a timed-out desktop lane lock - #58

Merged
iamnbutler merged 1 commit into
mainfrom
fix/lane-lock-holder
Oct 17, 2026
Merged

iamnbutler merged 1 commit into
mainfrom
fix/lane-lock-holder

Conversation

@iamnbutler

@iamnbutler iamnbutler commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Closes #48. The coordination root stays shared, by decision.

When a desktop lane lock wait timed out, the error gave only the path ("Timed out waiting for the desktop operation lane lock at ~/.peekaboo/global.lock"). Neither the agent nor the user could see that a hung swift test helper was the cause.

Change

New patch at the end of the stack: peekaboo-lock-holder.patch.

  • Message. On a lane-lock timeout, DesktopOperationLaneCoordinator.checkLockDeadline now appends "Processes with it open, one of which holds it:" and lists up to 8 processes. Each has its name, pid and executable path. The timed-out process is marked this process.
    • Example: … lane lock at /Users/me/.peekaboo/global.lock. Processes with it open, one of which holds it: swiftpm-testing-helper (pid 35219, /…/swiftpm-testing-helper); desktop-tools-app (pid 812, this process, /Applications/Desktop Tools.app/…).
  • Why "open" and not "holds". flock records no owner, and lsof can't tell holders from waiters. F_GETLK sees a flock conflict but reports l_pid = -1; I checked both here. So the new LockFileHolders walks the user's processes' open file descriptors with proc_listallpids, PROC_PIDLISTFDS and PROC_PIDFDVNODEPATHINFO, and matches the lock file by device and inode. The holder is always in the list, along with any other waiters. The lookup takes about 0.2 s and runs only after a 15 s timeout.
  • Hint.
    • With processes found: "Another process holds the desktop lock. If one listed is stuck, such as a test run, tell the user which one; do not retry in a loop."
    • With none found: "wait, then observe again".
  • Unchanged. It is still a pre-dispatch refused with error code timeout. Other users' processes are unreadable and left out.
  • Docs. native/patches/README.md describes the patch. docs/build.md warns contributors that Peekaboo tests take the real ~/.peekaboo locks, that HOME doesn't isolate them, and to use a narrow filter and a time limit. This is the issue's third idea.

Coordination root

It stays shared, as the lead decided: serializing with other Peekaboo hosts, such as Ace, is the point.

Tests

  • swift test --filter DesktopOperationLaneCoordinatorTests in Core/PeekabooAutomationKit: 19/19 pass. It ran in the foreground with a 600 s limit and an uncommitted isolation edit to defaultURL, which was reverted before generating the patch. Two new tests:
    • A held lock in a temporary root times out with "one of which holds it", the "pid N, this process" entry and the new hint.
    • A file nobody has open, and a missing file, list no holders.
  • git apply --check -R confirms the patch is the exact delta on top of the current stack.
  • npm run check passes, and the native build is green.

Live check (pending)

  • Hold ~/.peekaboo/global.lock from a throwaway process, for example python3 -c 'import fcntl,time;f=open("<path>","a");fcntl.flock(f,fcntl.LOCK_EX);time.sleep(30)', then call desktop_windows → refused after 15 s, naming that Python process. I didn't run this: holding the real lock would block the live MCP and other workers.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@iamnbutler
iamnbutler force-pushed the fix/lane-lock-holder branch from b79e1cb to d5db3a5 Compare October 17, 2026 03:20
@iamnbutler
iamnbutler merged commit ab874bd into main Oct 17, 2026
2 checks passed
@iamnbutler
iamnbutler deleted the fix/lane-lock-holder branch October 17, 2026 03:25
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.

A hung process holding ~/.peekaboo/global.lock blocks every desktop operation

1 participant