Skip to content

fix(daemon): make idle disconnect updates atomic - #98

Open
NianJiuZst wants to merge 2 commits into
Tencent:mainfrom
NianJiuZst:codex/fix-daemon-idle-close-race
Open

fix(daemon): make idle disconnect updates atomic#98
NianJiuZst wants to merge 2 commits into
Tencent:mainfrom
NianJiuZst:codex/fix-daemon-idle-close-race

Conversation

@NianJiuZst

Copy link
Copy Markdown
Contributor

Summary

  • keep the last IPC activity timestamp and active connection count in one mutex-protected state
  • update connection close count and close timestamp atomically
  • recover poisoned activity-state locks consistently and avoid connection-count underflow
  • add deterministic boundary tests for close/activity idle windows

Why

The close callback previously decremented the atomic connection count before updating the separately locked activity timestamp. The idle task could observe the old expired timestamp between those operations, then see zero connections and shut the daemon down immediately after the last client disconnected instead of starting a fresh idle interval.

An idle check now observes a coherent snapshot: it sees either the still-open connection or the new close timestamp.

Tests

  • cargo test -p bsk --locked
  • cargo clippy -p bsk --all-targets --locked -- -D warnings
  • cargo test -p bsk --test idle_exit --locked -- --test-threads=1
  • repeated the last-connection disconnect regression 3 additional times

@NianJiuZst
NianJiuZst marked this pull request as ready for review August 17, 2026 07:21
@iuyo5678

Copy link
Copy Markdown
Collaborator

The race condition here only exists in the nanosecond-scale gap between two adjacent statements, so it is almost impossible to observe in real situation. But consolidating the two states that change together into a single invariant will avoid the same kind of bug again, so it is still worthwhile. Once the code comments are updated to match the code, it can be merged.

After folding the IPC connection count and activity timestamp into a
single mutex-protected IpcActivityState, the idle task no longer
references the connection count directly; should_exit_for_idle already
returns false while a connection is open or within the idle window.
Update the comment to describe the post-refactor control flow so it
matches the code.
@NianJiuZst
NianJiuZst force-pushed the codex/fix-daemon-idle-close-race branch from 9191f43 to 8352c3c Compare August 20, 2026 05:53

@NianJiuZst NianJiuZst left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. Per your note, the idle-task comment now matches the post-refactor control flow: should_exit_for_idle already enforces the zero-connection + idle-window invariant under the single IpcActivityState lock, so the remaining if block only holds the daemon alive while any browser is paired or any session is live (design §3.2, M4/M5 registries).

New head: 8352c3c (rebased onto current main@6b78211).

Verified locally after the rebase:

  • cargo test -p bsk --locked --lib -- ipc_close ipc_activity — both new unit tests pass.
  • cargo clippy -p bsk --all-targets --locked -- -D warnings — clean.
  • cargo test -p bsk --test idle_exit --locked -- --test-threads=1 — the integration tests need an actual daemon process binding a UDS in /var/folders/...; on this machine that bind is rejected by the sandbox (Operation not permitted (os error 1)), so I could not re-run them locally. The PR did not touch those tests; they should still be green on your CI.

No logic change, only the comment refresh.

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.

2 participants