bug 1255618 remove AudioContext from global window at unlink r=Ehsan a=ritu
authorKarl Tomlinson <karlt+@karlt.net>
Fri, 11 Mar 2016 20:54:31 +1300
changeset 310209 4087c90f63ae0f0b4b958471d28a81f52de292b2
parent 310208 34df95dbc0d58186c0a631f5f2dd7f633d8f33da
child 310210 d84ed6588b2365332c9fb6a42c58fefcffd65683
push id9296
push userkwierso@gmail.com
push dateWed, 23 Mar 2016 22:19:51 +0000
treeherdermozilla-aurora@d84ed6588b23 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEhsan, ritu
bugs1255618
milestone47.0a2
bug 1255618 remove AudioContext from global window at unlink r=Ehsan a=ritu 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;