Bug 1523013 - Clear SamplesWaitingForKey::mProxy in Shutdown(). r=cpearce a=lizzard
authorAndrew McCreight <continuation@gmail.com>
Wed, 30 Jan 2019 22:56:21 +0000
changeset 512876 1079d285dd4006cf27fd867d29c7e408a7627365
parent 512875 c916c1117a67cae04c6808de1e80824ab5cf13fb
child 512877 32e42cfd5f75027335205e600bf4cd241d6de773
push id10630
push usernbeleuzu@mozilla.com
push dateWed, 06 Feb 2019 10:44:39 +0000
treeherdermozilla-beta@6e1b209f1fd8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, lizzard
bugs1523013
milestone66.0
Bug 1523013 - Clear SamplesWaitingForKey::mProxy in Shutdown(). r=cpearce a=lizzard There's a strong cycle of references between SamplesWaitingForKey and CDMProxy that does not get cleared unless keys actually come in. This causes a leak. One way to avoid that leak is to clear the proxy reference when the things holding the SamplesWaitingForKey is shut down. Differential Revision: https://phabricator.services.mozilla.com/D17960
dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h
--- a/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
+++ b/dom/media/platforms/agnostic/eme/EMEDecoderModule.cpp
@@ -246,16 +246,17 @@ class EMEDecryptor : public MediaDataDec
     });
   }
 
   RefPtr<ShutdownPromise> Shutdown() override {
     RefPtr<EMEDecryptor> self = this;
     return InvokeAsync(mTaskQueue, __func__, [self, this]() {
       MOZ_ASSERT(!mIsShutdown);
       mIsShutdown = true;
+      mSamplesWaitingForKey->BreakCycles();
       mSamplesWaitingForKey = nullptr;
       RefPtr<MediaDataDecoder> decoder = mDecoder.forget();
       mProxy = nullptr;
       return decoder->Shutdown();
     });
   }
 
   nsCString GetDescriptionName() const override {
@@ -342,16 +343,17 @@ RefPtr<MediaDataDecoder::FlushPromise> E
     mDecodePromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
     return MediaDataDecoderProxy::Flush();
   });
 }
 
 RefPtr<ShutdownPromise> EMEMediaDataDecoderProxy::Shutdown() {
   RefPtr<EMEMediaDataDecoderProxy> self = this;
   return InvokeAsync(mThread, __func__, [self, this]() {
+    mSamplesWaitingForKey->BreakCycles();
     mSamplesWaitingForKey = nullptr;
     mProxy = nullptr;
     return MediaDataDecoderProxy::Shutdown();
   });
 }
 
 EMEDecoderModule::EMEDecoderModule(CDMProxy* aProxy, PDMFactory* aPDM)
     : mProxy(aProxy), mPDM(aPDM) {}
--- a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
+++ b/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.cpp
@@ -64,9 +64,14 @@ void SamplesWaitingForKey::NotifyUsable(
 void SamplesWaitingForKey::Flush() {
   MutexAutoLock lock(mMutex);
   for (auto& sample : mSamples) {
     sample.mPromise.Reject(true, __func__);
   }
   mSamples.Clear();
 }
 
+void SamplesWaitingForKey::BreakCycles() {
+  MutexAutoLock lock(mMutex);
+  mProxy = nullptr;
+}
+
 }  // namespace mozilla
--- a/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h
+++ b/dom/media/platforms/agnostic/eme/SamplesWaitingForKey.h
@@ -37,16 +37,18 @@ class SamplesWaitingForKey {
   // Returns a promise that will be resolved if or when a key for decoding the
   // sample becomes usable.
   RefPtr<WaitForKeyPromise> WaitIfKeyNotUsable(MediaRawData* aSample);
 
   void NotifyUsable(const CencKeyId& aKeyId);
 
   void Flush();
 
+  void BreakCycles();
+
  protected:
   ~SamplesWaitingForKey();
 
  private:
   Mutex mMutex;
   RefPtr<CDMProxy> mProxy;
   struct SampleEntry {
     RefPtr<MediaRawData> mSample;