You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A Drive that fails and rejoins inside one audio block can lose its new join request #945
If a Drive Copy is stopped and then asked to join again, both inside the few microseconds the audio thread spends on one join block, the new join request can be wiped. The Copy then never joins, or it is fed with no join frame set. This is in the real-time path (ADR 0002).
Why it matters
A Drive that rejoins and is never fed misses the rest of the Take on that Copy. A Copy fed with no join frame can put its Stems out of line with the Device's. The window is very narrow (a stop plus a reattach inside one block), so this is rare.
Done when
A deterministic test: a Copy stopped and then attached again while the audio thread is between reading the join requests and clearing them still joins at its next block, with its join frame set (red first).
The fix PR is merged, real-time safe (atomics only), after a human review of the diff (ADR 0002).
Eric's device Take from an internal TestFlight build before External testers.
Details
Found in the Code Reviewer's pass on PR #944 (#544). Older than that change; #944 doesn't touch it.
Two ways it goes wrong, in Packages/ShowRecorderKit/Sources/Recording/Capture.swift:
Lost request.receive loads joinRequests (line 212), then clears what it read with joinRequests.bitwiseAnd(~requested) (line 227). If, between those two lines, stopFeeding clears the Copy's bit (line 178) and attachMidTake sets it again (line 171), the clear at line 227 wipes the new request. The Copy is never fed and its writer waits for a join that never comes.
Fed with no join frame.attachMidTake calls feed.reset(joinedAt: nil) (line 170). If that lands after receive has already called markJoined(at:) (line 224) for the old request, the Copy is fed while its join frame reads nil, and no request is left pending to set it.
One option: have receive clear only the bits it acted on with a compare-and-exchange, or count requests (a generation per Copy) so a fresh request isn't mistaken for the one already read. Either one must stay atomics only.
Test seam:#944 adds afterJoinRead, a test-only hook between reading the requests and acting on them. A test can call stopFeeding and attachMidTake from inside it.
Activity
A Drive that fails and rejoins inside one audio block keeps its new j…
Release notes for v1.1.17 [internal] (#964)