Bug 1336356 - Ensure MediaDecode::Shutdown() is called by MediaShutdownManager::BlockShutdown(). r=gerald
authorJW Wang <jwwang@mozilla.com>
Fri, 03 Feb 2017 17:12:38 +0800
changeset 341128 b2d14d738d2c38bd56225340b4dad320fe50bc7d
parent 341127 6db058fe1d63d9f4d8dc5ecc7b77b0330abc96dd
child 341129 56b0d9ecb97b83a94f8edef1a44f3b3926facd5d
push id86634
push usercbook@mozilla.com
push dateTue, 07 Feb 2017 13:14:58 +0000
treeherdermozilla-inbound@9dbd2d9b334e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1336356
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1336356 - Ensure MediaDecode::Shutdown() is called by MediaShutdownManager::BlockShutdown(). r=gerald MozReview-Commit-ID: 80AFMafXoeB
dom/media/MediaDecoder.cpp
dom/media/MediaDecoder.h
dom/media/MediaDecoderOwner.h
dom/media/MediaShutdownManager.cpp
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -518,16 +518,32 @@ MediaDecoder::Shutdown()
   if (mResource) {
     mResource->Close();
   }
 
   ChangeState(PLAY_STATE_SHUTDOWN);
   mOwner = nullptr;
 }
 
+void
+MediaDecoder::NotifyXPCOMShutdown()
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  if (auto owner = GetOwner()) {
+    owner->NotifyXPCOMShutdown();
+  }
+  MOZ_DIAGNOSTIC_ASSERT(IsShutdown());
+
+  // Don't cause grief to release builds by ensuring Shutdown()
+  // is always called during shutdown phase.
+  if (!IsShutdown()) {
+    Shutdown();
+  }
+}
+
 MediaDecoder::~MediaDecoder()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(IsShutdown());
   mResourceCallback->Disconnect();
   MediaMemoryTracker::RemoveMediaDecoder(this);
   UnpinForSeek();
 }
--- a/dom/media/MediaDecoder.h
+++ b/dom/media/MediaDecoder.h
@@ -129,16 +129,21 @@ public:
   // Create a new state machine to run this decoder.
   // Subclasses must implement this.
   virtual MediaDecoderStateMachine* CreateStateMachine() = 0;
 
   // Cleanup internal data structures. Must be called on the main
   // thread by the owning object before that object disposes of this object.
   virtual void Shutdown();
 
+  // Notified by the shutdown manager that XPCOM shutdown has begun.
+  // The decoder should notify its owner to drop the reference to the decoder
+  // to prevent further calls into the decoder.
+  void NotifyXPCOMShutdown();
+
   // Start downloading the media. Decode the downloaded data up to the
   // point of the first frame of data.
   // This is called at most once per decoder, after Init().
   virtual nsresult Load(nsIStreamListener** aListener);
 
   // Called in |Load| to open mResource.
   nsresult OpenResource(nsIStreamListener** aStreamListener);
 
--- a/dom/media/MediaDecoderOwner.h
+++ b/dom/media/MediaDecoderOwner.h
@@ -137,17 +137,17 @@ public:
 
   // Called by the media decoder and the video frame to get the
   // ImageContainer containing the video data.
   virtual VideoFrameContainer* GetVideoFrameContainer() = 0;
 
   // Called by media decoder when the audible state changed
   virtual void SetAudibleState(bool aAudible) = 0;
 
-  // Notified by the shutdown manager that XPCOM shutdown has begun.
+  // Notified by the decoder that XPCOM shutdown has begun.
   // The decoder owner should call Shutdown() on the decoder and drop the
   // reference to the decoder to prevent further calls into the decoder.
   virtual void NotifyXPCOMShutdown() = 0;
 
   // Dispatches a "encrypted" event to the HTMLMediaElement, with the
   // provided init data. Actual dispatch may be delayed until HAVE_METADATA.
   // Main thread only.
   virtual void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
--- a/dom/media/MediaShutdownManager.cpp
+++ b/dom/media/MediaShutdownManager.cpp
@@ -149,22 +149,17 @@ MediaShutdownManager::BlockShutdown(nsIA
   auto oldCount = mDecoders.Count();
   if (oldCount == 0) {
     RemoveBlocker();
     return NS_OK;
   }
 
   // Iterate over the decoders and shut them down.
   for (auto iter = mDecoders.Iter(); !iter.Done(); iter.Next()) {
-    MediaDecoderOwner* owner = iter.Get()->GetKey()->GetOwner();
-    if (owner) {
-      // The owner will call MediaDecoder::Shutdown() and
-      // drop its reference to the decoder.
-      owner->NotifyXPCOMShutdown();
-    }
+    iter.Get()->GetKey()->NotifyXPCOMShutdown();
     // Check MediaDecoder::Shutdown doesn't call Unregister() synchronously in
     // order not to corrupt our hashtable traversal.
     MOZ_ASSERT(mDecoders.Count() == oldCount);
   }
 
   return NS_OK;
 }