From c9a7b41864dd3bc6162ee249dfa549eb8b86e822 Mon Sep 17 00:00:00 2001 From: ed Date: Wed, 16 Jan 2019 10:35:40 +0000 Subject: [PATCH] Made a few of the AudioIODeviceType subclasses weak referenceable to avoid dangling references --- .../native/juce_ios_Audio.cpp | 12 ++++---- .../native/juce_ios_Audio.h | 2 +- .../native/juce_mac_CoreAudio.cpp | 28 +++++++++++-------- .../native/juce_win32_WASAPI.cpp | 15 +++++++--- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/modules/juce_audio_devices/native/juce_ios_Audio.cpp b/modules/juce_audio_devices/native/juce_ios_Audio.cpp index 3383503d90..3574ad9884 100644 --- a/modules/juce_audio_devices/native/juce_ios_Audio.cpp +++ b/modules/juce_audio_devices/native/juce_ios_Audio.cpp @@ -235,6 +235,7 @@ private: SharedResourcePointer sessionHolder; + JUCE_DECLARE_WEAK_REFERENCEABLE (iOSAudioIODeviceType) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (iOSAudioIODeviceType) }; @@ -242,7 +243,7 @@ private: struct iOSAudioIODevice::Pimpl : public AudioPlayHead, public AsyncUpdater { - Pimpl (iOSAudioIODeviceType& ioDeviceType, iOSAudioIODevice& ioDevice) + Pimpl (iOSAudioIODeviceType* ioDeviceType, iOSAudioIODevice& ioDevice) : deviceType (ioDeviceType), owner (ioDevice) { @@ -416,7 +417,8 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, updateAvailableSampleRates(); updateAvailableBufferSizes(); - deviceType.callDeviceChangeListeners(); + if (deviceType != nullptr) + deviceType->callDeviceChangeListeners(); } void setTargetSampleRateAndBufferSize() @@ -1310,7 +1312,7 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, MidiMessageCollector* messageCollector = nullptr; - iOSAudioIODeviceType& deviceType; + WeakReference deviceType; iOSAudioIODevice& owner; CriticalSection callbackLock; @@ -1330,7 +1332,7 @@ struct iOSAudioIODevice::Pimpl : public AudioPlayHead, }; //============================================================================== -iOSAudioIODevice::iOSAudioIODevice (iOSAudioIODeviceType& ioDeviceType, const String&, const String&) +iOSAudioIODevice::iOSAudioIODevice (iOSAudioIODeviceType* ioDeviceType, const String&, const String&) : AudioIODevice (iOSAudioDeviceName, iOSAudioDeviceName), pimpl (new Pimpl (ioDeviceType, *this)) { @@ -1404,7 +1406,7 @@ bool iOSAudioIODeviceType::hasSeparateInputsAndOutputs() const { retu AudioIODevice* iOSAudioIODeviceType::createDevice (const String& outputDeviceName, const String& inputDeviceName) { - return new iOSAudioIODevice (*this, outputDeviceName, inputDeviceName); + return new iOSAudioIODevice (this, outputDeviceName, inputDeviceName); } void iOSAudioIODeviceType::handleRouteChange (AVAudioSessionRouteChangeReason) diff --git a/modules/juce_audio_devices/native/juce_ios_Audio.h b/modules/juce_audio_devices/native/juce_ios_Audio.h index e3f86943da..97ad348771 100644 --- a/modules/juce_audio_devices/native/juce_ios_Audio.h +++ b/modules/juce_audio_devices/native/juce_ios_Audio.h @@ -77,7 +77,7 @@ public: private: //============================================================================== - iOSAudioIODevice (iOSAudioIODeviceType&, const String&, const String&); + iOSAudioIODevice (iOSAudioIODeviceType*, const String&, const String&); //============================================================================== friend class iOSAudioIODeviceType; diff --git a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp index fdf234e809..0e78b0c831 100644 --- a/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp +++ b/modules/juce_audio_devices/native/juce_mac_CoreAudio.cpp @@ -887,7 +887,9 @@ private: case kAudioDevicePropertyDeviceHasChanged: case kAudioObjectPropertyOwnedObjects: intern->owner.restart(); - intern->owner.deviceType.triggerAsyncAudioDeviceListChange(); + + if (intern->owner.deviceType != nullptr) + intern->owner.deviceType->triggerAsyncAudioDeviceListChange(); break; case kAudioDevicePropertyBufferSizeRange: @@ -946,7 +948,7 @@ class CoreAudioIODevice : public AudioIODevice, private Timer { public: - CoreAudioIODevice (CoreAudioIODeviceType& dt, + CoreAudioIODevice (CoreAudioIODeviceType* dt, const String& deviceName, AudioDeviceID inputDeviceId, const int inputIndex_, AudioDeviceID outputDeviceId, const int outputIndex_) @@ -1109,7 +1111,8 @@ public: void audioDeviceListChanged() { - deviceType.audioDeviceListChanged(); + if (deviceType != nullptr) + deviceType->audioDeviceListChanged(); } void restart() @@ -1146,7 +1149,7 @@ public: deviceWrapperRestartCallback = cb; } - CoreAudioIODeviceType& deviceType; + WeakReference deviceType; int inputIndex, outputIndex; private: @@ -1199,7 +1202,7 @@ class AudioIODeviceCombiner : public AudioIODevice, private Timer { public: - AudioIODeviceCombiner (const String& deviceName, CoreAudioIODeviceType& deviceType) + AudioIODeviceCombiner (const String& deviceName, CoreAudioIODeviceType* deviceType) : AudioIODevice (deviceName, "CoreAudio"), Thread (deviceName), owner (deviceType) @@ -1553,7 +1556,7 @@ public: } private: - CoreAudioIODeviceType& owner; + WeakReference owner; CriticalSection callbackLock; AudioIODeviceCallback* callback = nullptr; AudioIODeviceCallback* previousCallback = nullptr; @@ -1775,8 +1778,8 @@ private: } } - if (anySampleRateChanges) - owner.audioDeviceListChanged(); + if (anySampleRateChanges && owner != nullptr) + owner->audioDeviceListChanged(); if (callback != nullptr) callback->audioDeviceAboutToStart (device); @@ -2160,20 +2163,20 @@ public: : outputDeviceName; if (inputDeviceID == outputDeviceID) - return new CoreAudioIODevice (*this, combinedName, inputDeviceID, inputIndex, outputDeviceID, outputIndex); + return new CoreAudioIODevice (this, combinedName, inputDeviceID, inputIndex, outputDeviceID, outputIndex); std::unique_ptr in, out; if (inputDeviceID != 0) - in.reset (new CoreAudioIODevice (*this, inputDeviceName, inputDeviceID, inputIndex, 0, -1)); + in.reset (new CoreAudioIODevice (this, inputDeviceName, inputDeviceID, inputIndex, 0, -1)); if (outputDeviceID != 0) - out.reset (new CoreAudioIODevice (*this, outputDeviceName, 0, -1, outputDeviceID, outputIndex)); + out.reset (new CoreAudioIODevice (this, outputDeviceName, 0, -1, outputDeviceID, outputIndex)); if (in == nullptr) return out.release(); if (out == nullptr) return in.release(); - std::unique_ptr combo (new AudioIODeviceCombiner (combinedName, *this)); + std::unique_ptr combo (new AudioIODeviceCombiner (combinedName, this)); combo->addDevice (in.release(), true, false); combo->addDevice (out.release(), false, true); return combo.release(); @@ -2235,6 +2238,7 @@ private: audioDeviceListChanged(); } + JUCE_DECLARE_WEAK_REFERENCEABLE (CoreAudioIODeviceType) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioIODeviceType) }; diff --git a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp index 70d36801a5..def3648a8c 100644 --- a/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp +++ b/modules/juce_audio_devices/native/juce_win32_WASAPI.cpp @@ -1518,7 +1518,7 @@ private: class ChangeNotificationClient : public ComBaseClassHelper { public: - ChangeNotificationClient (WASAPIAudioIODeviceType& d) + ChangeNotificationClient (WASAPIAudioIODeviceType* d) : ComBaseClassHelper (0), device (d) {} HRESULT STDMETHODCALLTYPE OnDeviceAdded (LPCWSTR) { return notify(); } @@ -1528,9 +1528,15 @@ private: HRESULT STDMETHODCALLTYPE OnPropertyValueChanged (LPCWSTR, const PROPERTYKEY) { return notify(); } private: - WASAPIAudioIODeviceType& device; + WeakReference device; - HRESULT notify() { device.triggerAsyncDeviceChangeCallback(); return S_OK; } + HRESULT notify() + { + if (device != nullptr) + device->triggerAsyncDeviceChangeCallback(); + + return S_OK; + } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ChangeNotificationClient) }; @@ -1571,7 +1577,7 @@ private: if (! check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator)))) return; - notifyClient = new ChangeNotificationClient (*this); + notifyClient = new ChangeNotificationClient (this); enumerator->RegisterEndpointNotificationCallback (notifyClient); } @@ -1660,6 +1666,7 @@ private: } //============================================================================== + JUCE_DECLARE_WEAK_REFERENCEABLE (WASAPIAudioIODeviceType) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIAudioIODeviceType) };