From 209a34c2b7031851631b0b059071a8d3ececab00 Mon Sep 17 00:00:00 2001 From: Karl Tomlinson Date: Fri, 12 Jun 2020 03:53:34 +0000 Subject: [PATCH] Bug 1642849 shut down MediaTrackGraph from AudioContext when window will be destroyed r=padenot Differential Revision: https://phabricator.services.mozilla.com/D74814 --- dom/base/nsGlobalWindowInner.cpp | 2 +- dom/media/webaudio/AudioContext.cpp | 19 ++++++++++++++----- dom/media/webaudio/AudioContext.h | 2 +- dom/media/webaudio/AudioDestinationNode.cpp | 5 +---- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index bb4986d7f9b9..10c4f9e1d107 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -1137,7 +1137,7 @@ void nsGlobalWindowInner::FreeInnerObjects() { NotifyWindowIDDestroyed("inner-window-destroyed"); for (uint32_t i = 0; i < mAudioContexts.Length(); ++i) { - mAudioContexts[i]->Shutdown(); + mAudioContexts[i]->OnWindowDestroy(); } mAudioContexts.Clear(); diff --git a/dom/media/webaudio/AudioContext.cpp b/dom/media/webaudio/AudioContext.cpp index 8543fee9b1ab..b4d373f3afea 100644 --- a/dom/media/webaudio/AudioContext.cpp +++ b/dom/media/webaudio/AudioContext.cpp @@ -743,11 +743,11 @@ nsISerialEventTarget* AudioContext::GetMainThread() const { void AudioContext::DisconnectFromOwner() { mIsDisconnecting = true; - Shutdown(); + OnWindowDestroy(); DOMEventTargetHelper::DisconnectFromOwner(); } -void AudioContext::Shutdown() { +void AudioContext::OnWindowDestroy() { // Avoid resend the Telemetry data. if (!mIsShutDown) { MaybeUpdateAutoplayTelemetryWhenShutdown(); @@ -776,9 +776,18 @@ void AudioContext::Shutdown() { // PBrowser::Destroy() message before xpcom shutdown begins. ShutdownWorklet(); - // For offline contexts, we can destroy the MediaTrackGraph at this point. - if (mIsOffline && mDestination) { - mDestination->OfflineShutdown(); + if (mDestination) { + // We can destroy the MediaTrackGraph at this point. + // Although there may be other clients using the graph, this graph is used + // only for clients in the same window and this window is going away. + // This will also interrupt any worklet script still running on the graph + // thread. + Graph()->ForceShutDown(); + // AudioDestinationNodes on rendering offline contexts have a + // self-reference which needs removal. + if (mIsOffline) { + mDestination->OfflineShutdown(); + } } } diff --git a/dom/media/webaudio/AudioContext.h b/dom/media/webaudio/AudioContext.h index 1812e79bcefb..ccc834ff9a23 100644 --- a/dom/media/webaudio/AudioContext.h +++ b/dom/media/webaudio/AudioContext.h @@ -151,7 +151,7 @@ class AudioContext final : public DOMEventTargetHelper, virtual void DisconnectFromOwner() override; - void Shutdown(); // idempotent + void OnWindowDestroy(); // idempotent JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; diff --git a/dom/media/webaudio/AudioDestinationNode.cpp b/dom/media/webaudio/AudioDestinationNode.cpp index b18ea7a2969b..67f6c7dceda2 100644 --- a/dom/media/webaudio/AudioDestinationNode.cpp +++ b/dom/media/webaudio/AudioDestinationNode.cpp @@ -488,10 +488,7 @@ void AudioDestinationNode::OfflineShutdown() { MOZ_ASSERT(Context() && Context()->IsOffline(), "Should only be called on a valid OfflineAudioContext"); - if (mTrack) { - mTrack->Graph()->MediaTrackGraph::ForceShutDown(); - mOfflineRenderingRef.Drop(this); - } + mOfflineRenderingRef.Drop(this); } JSObject* AudioDestinationNode::WrapObject(JSContext* aCx,