Bug 1336356 - Ensure MediaDecode::Shutdown() is called by MediaShutdownManager::BlockShutdown().
MozReview-Commit-ID: 80AFMafXoeB
--- a/dom/media/MediaDecoder.cpp
+++ b/dom/media/MediaDecoder.cpp
@@ -514,16 +514,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
@@ -125,16 +125,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;
}