fix: data races and invalid SVG icon in recorders and menu bar - #18
Open
Chukwuebuka-2003 wants to merge 2 commits into
Open
fix: data races and invalid SVG icon in recorders and menu bar#18Chukwuebuka-2003 wants to merge 2 commits into
Chukwuebuka-2003 wants to merge 2 commits into
Conversation
added 2 commits
July 29, 2026 22:59
Both recorder classes shared mutable state (file, firstBufferAt)
between the main thread and audio-tap / IOProc callbacks without
synchronization — a Swift undefined behavior under strict concurrency
and a real crash risk under load or on arm64 with compiler reordering.
Replace bare stored properties with OSAllocatedUnfairLock-backed
computed properties. The LockedState struct holds the two fields;
every read/write on either thread goes through state.withLock { }.
Liveness-check fields (livenessFrames, livenessPeak, livenessSettled)
remain plain because they are written only in the tap callback and
read only via DispatchQueue.main.async (fallBackToRaw), which
establishes a happens-before ordering.
Each line of the inlined SVG ended with `\\` (escaped backslash) which produced a literal `\` before the newline in the runtime string. Inside the <svg> opening tag this is not valid XML — a bare `\` is neither whitespace nor a valid attribute name character. NSImage's WebKit-based SVG parser silently recovers from the error in practice, but this is fragile. The trailing `\` line continuations were superfluous anyway (the newlines and indentation are valid XML whitespace), so removing them yields a correct, parseable SVG.
FernandoGomes83
added a commit
to FernandoGomes83/quill
that referenced
this pull request
Jul 31, 2026
… OSAllocatedUnfairLock, fix SVG icon
FernandoGomes83
added a commit
to FernandoGomes83/quill
that referenced
this pull request
Jul 31, 2026
…onfigures the input device Conflict with digimata#18 in MicRecorder: kept digimata#18's OSAllocatedUnfairLock-backed LockedState and routed digimata#2's code through the computed properties. digimata#2's new lastBufferAt has the same cross-thread access pattern (written from the tap, read on main during the restart), so it joins the same locked state rather than sitting outside it.
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.
Fixes
1. Data races in MicRecorder and SystemAudioRecorder
Both recorder classes share mutable state (
file,firstBufferAt) between the main thread and audio-tap / IOProc callbacks without any synchronization. Reading a stored property from one thread while writing from another is undefined behavior in Swift's memory model.Wrap the two cross-thread fields in an
OSAllocatedUnfairLock-backedLockedStatestruct. Every read and write on either thread goes throughstate.withLock { }.2. Invalid feather SVG icon
The inlined feather SVG used
\at line endings as Swift line continuations, but the double-escape\\produced a literal backslash before each newline in the runtime string. Inside the<svg>opening tag a bare backslash is not valid XML — neither whitespace nor a valid attribute name character.NSImage's WebKit-based SVG parser silently recovers in practice, but this is fragile. Removed the superfluous backslash continuations; newlines between attributes are valid XML whitespace.
Files changed
Sources/quill/Audio/MicRecorder.swift(+24/-3)Sources/quill/Audio/SystemAudioRecorder.swift(+21/-2)Sources/quill/UI/MenuBarController.swift(+6/-6)