Repository navigation
Conversation
|
@Luccacvb is attempting to deploy a commit to the Margelo Team on Vercel. A member of the Team first needs to authorize it. |
This branch has not been deployed
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 #4156. Related: #4209 (same assertion, its scenario isn't reproduced here).
What
When an output is reused in a new
CameraSessionafter the previous one was torn down withstop()+configure([])(what<Camera>does on unmount), the app aborts later, when Hermes frees the old session:An output removed from a stopped
AVCaptureSessionis only detached when that session deallocates (thedealloc->_makeConfigurationLive:frames above), and that late detach asserts if another session took the output in the meantime. An output that outlives its<Camera>can hit this, e.g. ausePhotoOutput()in a screen that unmounts and remounts the<Camera>. #4156 hits it with a frame output and a barcode scanner output.How
When
configure([])empties a session that is stopped and not interrupted,HybridCameraSessionswaps in a newAVCaptureSessionand releases the old one inside that call, on the session queue. All sessions share that serial queue, so the old session deallocates and detaches its outputs before another session can add them. Listeners are moved over to the new instance.The assertion compares the session being detached with the one the output currently belongs to, so it only fires after a reuse. The
deinittried in #4209 also releases on the session queue, but at GC time, which can be after the output was reused. Releasing insideconfigure([])happens before any reuse, and without reuse the release doesn't abort (5/5 on device, see below).Preview layers that didn't get their connection because a later configure step threw are now detached as well, so they can't keep the old session alive.
#3800 moves
configure([])beforestop()in the<Camera>teardown. Doing that by hand on main didn't abort (1 run), but it doesn't help when the session is already stopped (isActive={false}) or whenstop()+configure([])are called directly.Test
visioncamera.multi-output.harness.ts: takes a photo in session A, tears A down withstop()+configure([])like<Camera>does, uses the same photo output in session B, takes a photo, then callsgc()so Hermes frees A. On an iPhone 14 (iOS 26.1), main aborts insidegc()with the stack above (4/4 runs), with this PR it passes (3/3). The first commit only adds this test.visioncamera.session.harness.ts: listeners keep firing afterconfigure([])+ reconfigure, andremove()still works after the swap.Also checked on the same device:
configure([])commits, without reuse: no abort, 5/5 on main and 5/5 with this PR<Camera>replaced by a new<Camera>with the same photo output, thengc(): aborts on main, passes with this PR (1 run each)gc()in between: passes with this PR (1 run)multi-outputandsessionfiles: pass with this PRphoto,controller,coordinates,nativepreviewview,hooks. These fail on both:locks metering modes after focusTo with locked adaptiveness,maps a square Frame region onto a square View region,starts a replacement preview and stops the removed preview while running,updates onUIRotationChanged when the interface orientation changescamera-view,video,barcode-scanner,frame-converter,skia-cameraAndroid: both new tests pass on an emulator, no Android changes.
Not covered
AVCaptureSession, since swapping it would drop the system's auto-resume.stop()returns early while interrupted (isRunningis false), so that path may still hit this.configure(...)on a stopped session and then added to another session can still hit the same late detach.