bug 1255618 remove AudioContext from global window at unlink r?ehsan draft
authorKarl Tomlinson <karlt+@karlt.net>
Fri, 11 Mar 2016 20:54:31 +1300
changeset 339691 4eb4787a255f77b6a734ef30ac9d59bae50fbe0f
parent 339537 946ed22cad04431c75ab5093989dfedf1bae5a3e
child 339882 3f2bc42d3570a51ba9506954ca89801b24e1ab3d
child 340336 40e1e01e40ea7abc3b29e66d837c0bc7d7ff9c90
push id12802
push userktomlinson@mozilla.com
push dateSat, 12 Mar 2016 23:49:04 +0000
reviewersehsan
bugs1255618
milestone48.0a1
bug 1255618 remove AudioContext from global window at unlink r?ehsan mDestination is cleared during unlink, which means that after that point the window can't do much with the AudioContext, nor should need to do so. MozReview-Commit-ID: E45aCpEfJEu
dom/media/webaudio/AudioContext.cpp
dom/media/webaudio/AudioContext.h
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -55,16 +55,19 @@ static dom::AudioContext::AudioContextId
 NS_IMPL_CYCLE_COLLECTION_CLASS(AudioContext)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mDestination)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mListener)
   if (!tmp->mIsStarted) {
     NS_IMPL_CYCLE_COLLECTION_UNLINK(mActiveNodes)
   }
+  // Remove weak reference on the global window as the context is not usable
+  // without mDestination.
+  tmp->DisconnectFromWindow();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END_INHERITED(DOMEventTargetHelper)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AudioContext,
                                                   DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDestination)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mListener)
   if (!tmp->mIsStarted) {
     MOZ_ASSERT(tmp->mIsOffline,
@@ -132,23 +135,28 @@ AudioContext::Init()
       return rv;
     }
     mDestination->SetIsOnlyNodeForContext(true);
   }
 
   return NS_OK;
 }
 
-AudioContext::~AudioContext()
+void
+AudioContext::DisconnectFromWindow()
 {
   nsPIDOMWindowInner* window = GetOwner();
   if (window) {
     window->RemoveAudioContext(this);
   }
+}
 
+AudioContext::~AudioContext()
+{
+  DisconnectFromWindow();
   UnregisterWeakMemoryReporter(this);
 }
 
 JSObject*
 AudioContext::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   if (mIsOffline) {
     return OfflineAudioContextBinding::Wrap(aCx, this, aGivenProto);
--- a/dom/media/webaudio/AudioContext.h
+++ b/dom/media/webaudio/AudioContext.h
@@ -307,16 +307,17 @@ public:
   void OnStateChanged(void* aPromise, AudioContextState aNewState);
 
   BasicWaveFormCache* GetBasicWaveFormCache();
 
   IMPL_EVENT_HANDLER(mozinterruptbegin)
   IMPL_EVENT_HANDLER(mozinterruptend)
 
 private:
+  void DisconnectFromWindow();
   void RemoveFromDecodeQueue(WebAudioDecodeJob* aDecodeJob);
   void ShutdownDecoder();
 
   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
   NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
                             nsISupports* aData, bool aAnonymize) override;
 
   friend struct ::mozilla::WebAudioDecodeJob;