Encapsulate transport state in TransportState struct#961
Draft
sbooth wants to merge 22 commits into
Draft
Conversation
This attempts to minimize the use of locks on UI-facing methods.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a detail::TransportSnapshot to provide a consistent, UI-friendly view of transport/playback state without taking activeDecodersMutex_, aiming to reduce lock contention on UI-facing methods.
Changes:
- Adds
detail::TransportSnapshotand routes playback position/time queries through a snapshot loaded via a seqlock-like mechanism. - Refactors seeking to use event-driven
seekRequest/seekCompletecommands and decouples seek requests from direct decoder-state mutation. - Publishes transport snapshots at key points in decoder lifecycle and render-event processing.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| Sources/CSFBAudioEngine/Player/AudioPlayer.mm | Implements snapshot publish/load logic and refactors seeking/event processing to rely on snapshots and new seek events. |
| Sources/CSFBAudioEngine/Player/AudioPlayer.h | Introduces detail::TransportSnapshot, adds snapshot storage fields, and inlines playback position/time methods to read snapshots. |
Comments suppressed due to low confidence (3)
Sources/CSFBAudioEngine/Player/AudioPlayer.mm:2305
loadTransportSnapshot()relies on copyingcurrentSnapshot_non-atomically and then uses an acquire fence followed by a relaxed sequence reload. This doesn't provide the usual seqlock acquire semantics and (combined with the plain struct copy) can allow torn/stale reads. Switching the snapshot copy tostd::atomic_refand making the second sequence loadmemory_order_acquiregives the intended synchronization with the writer’s finalmemory_order_releasestore.
const auto seq = snapshotSequence_.load(std::memory_order_acquire);
// If seq is odd, a writer is currently updating the snapshot
if ((seq & 1) != 0) [[unlikely]] {
#if DEBUG
os_log_debug(log_, "Unable to load playback snapshot: write in progress");
#endif /* DEBUG */
cpuPause();
Sources/CSFBAudioEngine/Player/AudioPlayer.mm:1203
- This log message still says "decoder seek event" even though the enqueued command is now
EventCommand::seekComplete. Updating the wording will make fault reports easier to interpret.
This issue also appears on line 1256 of the same file.
if (events_.enqueue(EventCommand::seekComplete, decoderState->sequenceNumber_, framePosition.value())) {
eventSemaphore_.signal();
} else {
os_log_fault(log_, "Error writing decoder seek event");
}
Sources/CSFBAudioEngine/Player/AudioPlayer.mm:1261
- This log message still says "decoder seek event" even though the enqueued command is now
EventCommand::seekComplete. Updating the wording will make fault reports easier to interpret.
if (events_.enqueue(EventCommand::seekComplete, nextDecoderState->sequenceNumber_,
framePosition.value())) {
eventSemaphore_.signal();
} else {
os_log_fault(log_, "Error writing decoder seek event");
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+516
to
+518
| #if DEBUG | ||
| assert(position != nullptr || time != nullptr); | ||
| #endif /* DEBUG */ |
Comment on lines
+1819
to
+1823
| } else { | ||
| os_log_error(log_, "Decoder state with sequence number %llu missing for seek request event", | ||
| sequenceNumber); | ||
| return false; | ||
| } |
Comment on lines
+2313
to
+2315
| #if DEBUG | ||
| os_log_debug(log_, "Unable to load playback snapshot: write in progress"); | ||
| #endif /* DEBUG */ |
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.
This attempts to minimize the use of locks on UI-facing methods.