fix(osx): make ofAVFoundationPlayer::close() synchronous and single-shot - #8527
Open
smeyfroi wants to merge 1 commit into
Open
fix(osx): make ofAVFoundationPlayer::close() synchronous and single-shot#8527smeyfroi wants to merge 1 commit into
smeyfroi wants to merge 1 commit into
Conversation
Fixes an intermittent crash on application exit reported on an AVFoundation internal queue (com.apple.coremedia.player.async.<addr>.P/GT). Two independent asynchronous teardowns of the same player object were in flight, and neither was waited for: 1. close() called -close, which is unloadVideoAsync. That nils _player, _playerItem, _videoOutput and _asset on the calling thread but defers cancelReading, cancelPendingSeeks, the KVO and NSNotificationCenter removals, -removeOutput:, -removeTimeObserver: and the CFRelease of the sample buffers to a block on a global concurrent queue. close() returned immediately. 2. close() also left videoPlayer non-null, so ~ofAVFoundationPlayer -> disposePlayer() dispatched a second -unloadVideo of the same object on another queue. Both take asyncLock and both can signal deallocCond. At exit the process goes on to destroy the GL context and run atexit handlers and static destructors concurrently with those blocks and with the AVPlayer's own serial queue. The player was also never paused, so it was still playing when closed. Pause so CoreMedia winds down at rate 0, use the existing blocking -unloadVideo so close() returns only once AVFoundation has finished, and null the handle so disposePlayer() finds nothing to dispatch. No API change; -unloadVideo is already present and is the synchronous sibling of the call being replaced.
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.
Problem
Intermittent crash on application exit, reported on an AVFoundation internal queue (
com.apple.coremedia.player.async.<addr>.P/GT), whenever the app quits while a video is loaded. Reproduced on macOS 26 / Apple silicon; the crash is timing-dependent and hits perhaps one exit in five under a playing video.Cause
Two independent asynchronous teardowns of the same player object were in flight, and neither was waited for:
close()called-close, which isunloadVideoAsync. That nils_player,_playerItem,_videoOutputand_asseton the calling thread but deferscancelReading,cancelPendingSeeks, the KVO and NSNotificationCenter removals,-removeOutput:,-removeTimeObserver:and theCFReleaseof the sample buffers to a block on a global concurrent queue.close()returned immediately.close()also leftvideoPlayernon-null, so~ofAVFoundationPlayer→disposePlayer()dispatched a second-unloadVideoof the same object on another queue. Both takeasyncLockand both can signaldeallocCond.At exit the process goes on to destroy the GL context and run
atexithandlers and static destructors concurrently with those blocks and with the AVPlayer's own serial queue. The player was also never paused, so it was still playing when closed.Fix
Pause so CoreMedia winds down at rate 0, use the existing blocking
-unloadVideosoclose()returns only once AVFoundation has finished, and null the handle sodisposePlayer()finds nothing to dispatch. No API change;-unloadVideois already present and is the synchronous sibling of the call being replaced.Verification
With the patch, repeated quit-during-playback cycles no longer crash; without it the CoreMedia-queue crash reproduces intermittently on exit.