Bug 1550737 - When shutdown is finished use only a reference of the child. r=jya
authorAlex Chronopoulos <achronop@gmail.com>
Thu, 16 May 2019 12:59:37 +0000
changeset 535977 5ba6d20ec80ad5dcabead733c7bd77df18aa05d7
parent 535976 d4bbc018fe902044fb90f08b6dc2c0a0d172423d
child 535978 b76c9bbbe88188ba4216fe94a9779370654bea20
push id2082
push userffxbld-merge
push dateMon, 01 Jul 2019 08:34:18 +0000
treeherdermozilla-release@2fb19d0466d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1550737, 1545416
milestone68.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 1550737 - When shutdown is finished use only a reference of the child. r=jya When `RemoteMediaDataDecoder::Shutdown` is finished it is not necessary to hold a reference of the `self` any more. Keep the `mChild` alive, which is the only one needed to destroy the IPDL. In addition to that, deleting the IPDL and destroying the child will be happening at the task queue similar to what was happening before Bug 1545416. Differential Revision: https://phabricator.services.mozilla.com/D31261
dom/media/ipc/RemoteMediaDataDecoder.cpp
--- a/dom/media/ipc/RemoteMediaDataDecoder.cpp
+++ b/dom/media/ipc/RemoteMediaDataDecoder.cpp
@@ -27,16 +27,23 @@ RemoteMediaDataDecoder::~RemoteMediaData
 
 RefPtr<MediaDataDecoder::InitPromise> RemoteMediaDataDecoder::Init() {
   RefPtr<RemoteMediaDataDecoder> self = this;
   return InvokeAsync(mAbstractManagerThread, __func__,
                      [self]() { return self->mChild->Init(); })
       ->Then(
           mAbstractManagerThread, __func__,
           [self, this](TrackType aTrack) {
+            // If shutdown has started in the meantime shutdown promise may
+            // be resloved before this task. In this case mChild will be null
+            // and the init promise has to be canceled.
+            if (!mChild) {
+              return InitPromise::CreateAndReject(NS_ERROR_DOM_MEDIA_CANCELED,
+                                                  __func__);
+            }
             mDescription =
                 mChild->GetDescriptionName() + NS_LITERAL_CSTRING(" (remote)");
             mIsHardwareAccelerated =
                 mChild->IsHardwareAccelerated(mHardwareAcceleratedReason);
             mConversion = mChild->NeedsConversion();
             return InitPromise::CreateAndResolve(aTrack, __func__);
           },
           [self](const MediaResult& aError) {
@@ -61,25 +68,33 @@ RefPtr<MediaDataDecoder::FlushPromise> R
 RefPtr<MediaDataDecoder::DecodePromise> RemoteMediaDataDecoder::Drain() {
   RefPtr<RemoteMediaDataDecoder> self = this;
   return InvokeAsync(mAbstractManagerThread, __func__,
                      [self]() { return self->mChild->Drain(); });
 }
 
 RefPtr<ShutdownPromise> RemoteMediaDataDecoder::Shutdown() {
   RefPtr<RemoteMediaDataDecoder> self = this;
-  return InvokeAsync(mAbstractManagerThread, __func__,
-                     [self]() { return self->mChild->Shutdown(); })
-      ->Then(mAbstractManagerThread, __func__,
-             [self](const ShutdownPromise::ResolveOrRejectValue& aValue) {
-               self->mChild->DestroyIPDL();
-               self->mChild = nullptr;
-               return ShutdownPromise::CreateAndResolveOrReject(aValue,
-                                                                __func__);
-             });
+  return InvokeAsync(mAbstractManagerThread, __func__, [self]() {
+    RefPtr<ShutdownPromise> p = self->mChild->Shutdown();
+
+    // We're about to be destroyed and drop our ref to
+    // *DecoderChild. Make sure we put a ref into the
+    // task queue for the *DecoderChild thread to keep
+    // it alive until we send the delete message.
+    p->Then(self->mManagerThread, __func__,
+            [child = RefPtr<IRemoteDecoderChild>(self->mChild.forget())](
+                const ShutdownPromise::ResolveOrRejectValue& aValue) {
+              MOZ_ASSERT(aValue.IsResolve());
+              child->DestroyIPDL();
+              return ShutdownPromise::CreateAndResolveOrReject(aValue,
+                                                               __func__);
+            });
+    return p;
+  });
 }
 
 bool RemoteMediaDataDecoder::IsHardwareAccelerated(
     nsACString& aFailureReason) const {
   aFailureReason = mHardwareAcceleratedReason;
   return mIsHardwareAccelerated;
 }