fix: close peer connections outside the engine lock (0.6.10) - #71
Merged
Merged
Conversation
Every "not responding" on 0.6.9 was the same deadlock. A roster change ran reconcile on the main thread, which closed the departed device's peer connection while holding the engine lock; that close waits for libwebrtc's signalling thread, and the signalling thread was delivering an ICE state callback that took the same lock. The three traces from the Pixel each show the main thread in PeerConnection.close under the lock and the signalling thread "waiting to lock, held by thread 1". Two rules now hold. Nothing that runs on a WebRTC callback takes the engine lock: link identity lives in a LinkTable readable from any thread and updateConnectionState takes no lock. And a link is closed only after the lock is released: reconcile, rebuild and the profile-one reopen hand the old link back and close it outside, as closeLinks always did. The engine's collectors also run on the media dispatcher rather than the caller's main thread, so a slow native close can no longer stall input even without a deadlock. LinkTableTest pins both rules: a state read completes while another thread holds the engine lock, and reconcile opens under the lock and hands back what is gone for closing outside it. Claude-Session: https://claude.ai/code/session_01TgQJ1LHZjQG6wiKVfZcXPs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every "not responding" on 0.6.9 was the same deadlock. A roster change ran reconcile on the main thread, which closed the departed device's peer connection while holding the engine lock; that close waits for libwebrtc's signalling thread, and the signalling thread was delivering an ICE state callback that took the same lock. The three traces from the Pixel each show the main thread in
PeerConnection.closeunder the lock and the signalling thread "waiting to lock, held by thread 1".Two rules now hold: nothing that runs on a WebRTC callback takes the engine lock (
LinkTable, lock-freeupdateConnectionState), and a link is closed only after the lock is released (reconcile, rebuild and the profile-one reopen hand the old link back). The engine's collectors run on the media dispatcher rather than the main thread.LinkTableTestpins both rules.Second commit bumps to 0.6.10 (33) and records the release in
docs/android-release.md. This build also carries the epoch admission proof from #70, which the deployed web keeper now requires.🤖 Generated with Claude Code
https://claude.ai/code/session_01TgQJ1LHZjQG6wiKVfZcXPs