diff --git a/src/effects/backends/audiounit/audiounitmanager.h b/src/effects/backends/audiounit/audiounitmanager.h index 7d6e5e8f1fd..032dd581911 100644 --- a/src/effects/backends/audiounit/audiounitmanager.h +++ b/src/effects/backends/audiounit/audiounitmanager.h @@ -45,6 +45,7 @@ class AudioUnitManager { private: QString m_name; std::atomic m_isInstantiated; + dispatch_group_t _Nonnull m_instantiationGroup; AudioUnit _Nullable m_audioUnit; AudioUnitManager(AVAudioUnitComponent* _Nullable component); diff --git a/src/effects/backends/audiounit/audiounitmanager.mm b/src/effects/backends/audiounit/audiounitmanager.mm index 8b8185593fc..8abda5b5d24 100644 --- a/src/effects/backends/audiounit/audiounitmanager.mm +++ b/src/effects/backends/audiounit/audiounitmanager.mm @@ -1,17 +1,17 @@ #import #import -#include "util/assert.h" +#import -#include #include -#include #include "effects/backends/audiounit/audiounitmanager.h" +#include "util/assert.h" AudioUnitManager::AudioUnitManager(AVAudioUnitComponent* _Nullable component) : m_name(component != nil ? QString::fromNSString([component name]) : "Unknown"), - m_isInstantiated(false) { + m_isInstantiated(false), + m_instantiationGroup(dispatch_group_create()) { } AudioUnitManagerPointer AudioUnitManager::create( @@ -59,22 +59,11 @@ } bool AudioUnitManager::waitForAudioUnit(int timeoutMs) const { - // NOTE: We use a sleep loop here since both a QWaitCondition and GCD - // DispatchGroup-based implementation seem to result in spurious crashes. - // See https://github.com/mixxxdj/mixxx/pull/13887#issuecomment-2486459443 - // TODO: Debug the precise issue - - QElapsedTimer timer; - timer.start(); - - while (!m_isInstantiated.load()) { - if (timer.elapsed() > timeoutMs) { - return false; - } - QThread::msleep(10); - } - - return true; + bool success = + dispatch_group_wait(m_instantiationGroup, + dispatch_time(DISPATCH_TIME_NOW, timeoutMs * 1000000)) == 0; + DEBUG_ASSERT(!success || m_isInstantiated.load()); + return success; } void AudioUnitManager::instantiateAudioUnitAsync( @@ -96,6 +85,8 @@ qDebug() << "Instantiating Audio Unit" << manager->m_name << "asynchronously"; + dispatch_group_enter(manager->m_instantiationGroup); + // TODO: Fix the weird formatting of blocks // clang-format off AudioComponentInstantiate(component.audioComponent, options, ^(AudioUnit _Nullable audioUnit, OSStatus error) { @@ -105,6 +96,7 @@ } manager->initializeWith(audioUnit); + dispatch_group_leave(manager->m_instantiationGroup); }); // clang-format on }