Bug 1316506 - Make Shutdown block on the manager thread so that we clear the callback pointer immediately. r=dvander
authorMatt Woodrow <mwoodrow@mozilla.com>
Sun, 13 Nov 2016 16:09:35 +1300
changeset 349059 7b08bfceec28d9b0d15c1373f0575424fcae30c7
parent 349058 94e24024f3d963c0d25c17be2b2a4c292d001f69
child 349060 3fc69a00d1a61242dd94cca745b94a46d6d49dd3
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs1316506
milestone52.0a1
Bug 1316506 - Make Shutdown block on the manager thread so that we clear the callback pointer immediately. r=dvander
dom/media/ipc/RemoteVideoDecoder.cpp
dom/media/ipc/VideoDecoderChild.cpp
dom/media/ipc/VideoDecoderParent.cpp
--- a/dom/media/ipc/RemoteVideoDecoder.cpp
+++ b/dom/media/ipc/RemoteVideoDecoder.cpp
@@ -6,16 +6,17 @@
 #include "RemoteVideoDecoder.h"
 #include "VideoDecoderChild.h"
 #include "VideoDecoderManagerChild.h"
 #include "mozilla/layers/TextureClient.h"
 #include "base/thread.h"
 #include "MediaInfo.h"
 #include "MediaPrefs.h"
 #include "ImageContainer.h"
+#include "mozilla/layers/SynchronousTask.h"
 
 namespace mozilla {
 namespace dom {
 
 using base::Thread;
 using namespace ipc;
 using namespace layers;
 using namespace gfx;
@@ -91,21 +92,24 @@ RemoteVideoDecoder::Drain()
     self->mActor->Drain();
   }), NS_DISPATCH_NORMAL);
 }
 
 void
 RemoteVideoDecoder::Shutdown()
 {
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
+  SynchronousTask task("Shutdown");
   RefPtr<RemoteVideoDecoder> self = this;
-  VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([self]() {
+  VideoDecoderManagerChild::GetManagerThread()->Dispatch(NS_NewRunnableFunction([&]() {
+    AutoCompleteTask complete(&task);
     MOZ_ASSERT(self->mActor);
     self->mActor->Shutdown();
   }), NS_DISPATCH_NORMAL);
+  task.Wait();
 }
 
 bool
 RemoteVideoDecoder::IsHardwareAccelerated(nsACString& aFailureReason) const
 {
   MOZ_ASSERT(mCallback->OnReaderTaskQueue());
   return mActor->IsHardwareAccelerated(aFailureReason);
 }
--- a/dom/media/ipc/VideoDecoderChild.cpp
+++ b/dom/media/ipc/VideoDecoderChild.cpp
@@ -47,41 +47,49 @@ VideoDecoderChild::RecvOutput(const Vide
   RefPtr<VideoData> video = VideoData::CreateFromImage(info,
                                                        aData.base().offset(),
                                                        aData.base().time(),
                                                        aData.base().duration(),
                                                        image,
                                                        aData.base().keyframe(),
                                                        aData.base().timecode(),
                                                        IntRect());
-  mCallback->Output(video);
+  if (mCallback) {
+    mCallback->Output(video);
+  }
   return true;
 }
 
 bool
 VideoDecoderChild::RecvInputExhausted()
 {
   AssertOnManagerThread();
-  mCallback->InputExhausted();
+  if (mCallback) {
+    mCallback->InputExhausted();
+  }
   return true;
 }
 
 bool
 VideoDecoderChild::RecvDrainComplete()
 {
   AssertOnManagerThread();
-  mCallback->DrainComplete();
+  if (mCallback) {
+    mCallback->DrainComplete();
+  }
   return true;
 }
 
 bool
 VideoDecoderChild::RecvError(const nsresult& aError)
 {
   AssertOnManagerThread();
-  mCallback->Error(aError);
+  if (mCallback) {
+    mCallback->Error(aError);
+  }
   return true;
 }
 
 bool
 VideoDecoderChild::RecvInitComplete(const bool& aHardware, const nsCString& aHardwareReason)
 {
   AssertOnManagerThread();
   mInitPromise.Resolve(TrackInfo::kVideoTrack, __func__);
@@ -102,17 +110,17 @@ VideoDecoderChild::RecvInitFailed(const 
 void
 VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (aWhy == AbnormalShutdown) {
     // Defer reporting an error until we've recreated the manager so that
     // it'll be safe for MediaFormatReader to recreate decoders
     RefPtr<VideoDecoderChild> ref = this;
     GetManager()->RunWhenRecreated(NS_NewRunnableFunction([=]() {
-      if (ref->mInitialized) {
+      if (ref->mInitialized && ref->mCallback) {
         ref->mCallback->Error(NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER);
       } else {
         ref->mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_NEED_NEW_DECODER, __func__);
       }
     }));
   }
   mCanSend = false;
 }
@@ -220,16 +228,17 @@ VideoDecoderChild::Drain()
     SendDrain();
   }
 }
 
 void
 VideoDecoderChild::Shutdown()
 {
   AssertOnManagerThread();
+  mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_CANCELED, __func__);
   if (mCanSend) {
     SendShutdown();
   }
   mInitialized = false;
 }
 
 bool
 VideoDecoderChild::IsHardwareAccelerated(nsACString& aFailureReason) const
--- a/dom/media/ipc/VideoDecoderParent.cpp
+++ b/dom/media/ipc/VideoDecoderParent.cpp
@@ -132,17 +132,19 @@ VideoDecoderParent::RecvInput(const Medi
   mDecoder->Input(data);
   return true;
 }
 
 bool
 VideoDecoderParent::RecvFlush()
 {
   MOZ_ASSERT(!mDestroyed);
-  mDecoder->Flush();
+  if (mDecoder) {
+    mDecoder->Flush();
+  }
   return true;
 }
 
 bool
 VideoDecoderParent::RecvDrain()
 {
   MOZ_ASSERT(!mDestroyed);
   mDecoder->Drain();