AUv3: lay the subview out at the agreed size, and serialize audio unit creation - #565
Merged
Merged
Conversation
The loadView bootstrap and the host's XPC factory call each built one, and the loser was released with its GUI still created.
defiantnerd
force-pushed
the
fix-553-auv3-view-and-bootstrap
branch
from
September 15, 2026 04:45
6c51d39 to
0858e04
Compare
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.
Closes #553. The issue holds two unrelated defects in one file; they are two commits here.
1. The subview ignored
adjust_size. After the container consultedadjust_size(added in #510), the layout pass still framed the subview from the raw container bounds — so an iPad rotation to landscape gave 1024x600 →adjust_size→ 800x600 → plugin lays out at 800x600 → frame forced back to 1024x600, stretched.setGUISize:height:now writes the adjusted size back into the cached_guiWidth/_guiHeight(that cache was previously only updated bygui_request_resize, so it went stale after every host-driven resize), and the layout pass reads the agreed size back rather than using bounds. Side benefit: a non-resizable plugin, wheresetGUISize:is never called, also stops being stretched to the container.2. Two AudioUnits could be created.
_bootstrapAttemptedguards re-entry on the main thread only — not against the host's factory call, which arrives on an XPC worker. Both could seeaudioUnit == niland build one; the property overwrite then released the bootstrap AU whose GUI already existed, sodeallocreachedterminate()withoutgui->destroy()(a CLAP contract violation, and a JUCE assert), while_tryCreateGUIran against the survivor whose_guiCreatedwas false — a permanently empty editor. A new-createAudioUnitOnce:error:on the base class holds one mutex, re-checks, and runs the caller's build block; both generated-code producers now funnel through it instead of doing their own unlocked check-then-act. No second AU is built, so there is no loser to tear down.Trade-off worth a reviewer's attention. Taking a real lock newly exposes one hazard: a plugin doing
dispatch_syncto the main queue from insideclap_plugin->init()would deadlock against a main thread parked on that lock. That is a plugin bug (initis[main-thread]), but it was not reachable before. The alternative —try_lockwith a placeholder-size fallback — would reintroduce the wrong-initial-size bug #510 fixed. There is nodispatch_syncanywhere inauv3_audiounit.mm, so nothing in the wrapper itself can deadlock here.Scope.
auv3_audiounit.hgains a five-line declaration so the generated subclasses can see the new method; the alternative was duplicating it as a category in both producers with no compiler cross-check.Verification. Compile-verified under the Xcode generator:
clap-first-distortion_auv3andclap-first-distortion_auv3_standaloneboth build after each commit, and the regeneratedgenerated_auv3_entrypoints.hxxin the build tree was confirmed to contain the new body, so the build-helper path is genuinely exercised. The iOS.hxx.intemplate is textually identical but was not compiled — no iOS toolchain here. Neither fix is runtime-tested: both need a physical iPad in AUM or GarageBand, and the race in commit 2 needs a slow-loading plugin to have any chance of reproducing.