This is an automated email from the git hooks/post-receive script.
richard pushed a commit to branch geckoview-102.3.0esr-12.0-1 in repository tor-browser.
commit ffc0e69dfd2c34b7e6eee61ccd639f1d02878d3f Author: David Parks daparks@mozilla.com AuthorDate: Fri Jul 29 19:32:15 2022 +0000
Bug 1755700: Serialize IAudioSessionControl destruction/re-creation r=cmartin, a=RyanVM
Destroying the IAudioSessionControl has concurrency issues with audio playback that require it to be done on the main thread. We have been trying to create a new AudioSessionControl on a background thread while this happens but some AudioSessionControl internals/dependencies are not thread safe. In order to avoid concurrency crashes, we destroy the old IAudioSessionControl on the main thread, then dispatch the restart to a background (MTA) thread asynchronously.
Differential Revision: https://phabricator.services.mozilla.com/D152302 --- widget/windows/AudioSession.cpp | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/widget/windows/AudioSession.cpp b/widget/windows/AudioSession.cpp index a9d683195e33d..a38e2a83f6de5 100644 --- a/widget/windows/AudioSession.cpp +++ b/widget/windows/AudioSession.cpp @@ -59,7 +59,7 @@ class AudioSession final : public IAudioSessionEvents { STDMETHODIMP OnStateChanged(AudioSessionState aState);
void Start(); - void Stop(); + void Stop(bool shouldRestart = false);
nsresult GetSessionData(nsID& aID, nsString& aSessionName, nsString& aIconPath); @@ -69,7 +69,8 @@ class AudioSession final : public IAudioSessionEvents { private: ~AudioSession() = default;
- void StopInternal(const MutexAutoLock& aProofOfLock); + void StopInternal(const MutexAutoLock& aProofOfLock, + bool shouldRestart = false);
protected: RefPtr<IAudioSessionControl> mAudioSessionControl; @@ -232,14 +233,15 @@ void AudioSession::Start() { scopeExit.release(); }
-void AudioSession::Stop() { +void AudioSession::Stop(bool shouldRestart) { MOZ_ASSERT(mscom::IsCurrentThreadMTA());
MutexAutoLock lock(mMutex); - StopInternal(lock); + StopInternal(lock, shouldRestart); }
-void AudioSession::StopInternal(const MutexAutoLock& aProofOfLock) { +void AudioSession::StopInternal(const MutexAutoLock& aProofOfLock, + bool shouldRestart) { if (!mAudioSessionControl) { return; } @@ -258,14 +260,22 @@ void AudioSession::StopInternal(const MutexAutoLock& aProofOfLock) { IID_IAudioSessionControl, mAudioSessionControl); mAudioSessionControl = nullptr; NS_DispatchToMainThread(NS_NewRunnableFunction( - "FreeAudioSession", - [agileAsc = std::move(agileAsc), IID_IAudioSessionControl] { + "FreeAudioSession", [agileAsc = std::move(agileAsc), + IID_IAudioSessionControl, shouldRestart] { RefPtr<IAudioSessionControl> toDelete; [[maybe_unused]] HRESULT hr = agileAsc->Resolve( IID_IAudioSessionControl, getter_AddRefs(toDelete)); MOZ_ASSERT(SUCCEEDED(hr)); // Now release the AgileReference which holds our only reference to the - // IAudioSessionControl. + // IAudioSessionControl, then maybe restart. + if (shouldRestart) { + NS_DispatchBackgroundTask( + NS_NewCancelableRunnableFunction("RestartAudioSession", [] { + AudioSession* as = AudioSession::GetSingleton(); + MOZ_ASSERT(as); + as->Start(); + })); + } })); }
@@ -322,8 +332,7 @@ AudioSession::OnIconPathChanged(LPCWSTR aIconPath, LPCGUID aContext) {
STDMETHODIMP AudioSession::OnSessionDisconnected(AudioSessionDisconnectReason aReason) { - Stop(); - Start(); + Stop(true /* shouldRestart */); return S_OK; }