Bug 1329385 - Fix leak in GMPServiceParent::GetContentParent - r=JamesCheng draft
authorGerald Squelart <gsquelart@mozilla.com>
Wed, 18 Jan 2017 08:55:57 +1100
changeset 704063 a7169d616da36597854bf37616228eb72636f2b7
parent 703941 f5f03ee9e6abf77964f8dc1b9d69c6ccd3f655fd
child 741987 fde8ec939066b883d3e2b15801cee46859afebb6
push id91061
push usergsquelart@mozilla.com
push dateTue, 28 Nov 2017 07:21:54 +0000
reviewersJamesCheng
bugs1329385
milestone59.0a1
Bug 1329385 - Fix leak in GMPServiceParent::GetContentParent - r=JamesCheng Using a single-function MozPromise::Then, and capturing a UniquePtr (using C++14 initialized lambda captures), the PromiseHolder cannot leak anymore. Also using C++ initialized lambda captures for other variables, to avoid unnecessary constructions and copies. MozReview-Commit-ID: DVxyuJNa8YX
dom/media/gmp/GMPServiceParent.cpp
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -359,44 +359,45 @@ GeckoMediaPluginServiceParent::GetConten
   const nsCString& aAPI,
   const nsTArray<nsCString>& aTags)
 {
   RefPtr<AbstractThread> thread(GetAbstractGMPThread());
   if (!thread) {
     return GetGMPContentParentPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
 
-  typedef MozPromiseHolder<GetGMPContentParentPromise> PromiseHolder;
-  PromiseHolder* rawHolder = new PromiseHolder();
-  RefPtr<GeckoMediaPluginServiceParent> self(this);
-  RefPtr<GetGMPContentParentPromise> promise = rawHolder->Ensure(__func__);
-  nsCString nodeIdString(aNodeIdString);
-  nsTArray<nsCString> tags(aTags);
-  nsCString api(aAPI);
-  RefPtr<GMPCrashHelper> helper(aHelper);
-  EnsureInitialized()->Then(
-    thread,
-    __func__,
-    [self, tags, api, nodeIdString, helper, rawHolder]() -> void {
-      UniquePtr<PromiseHolder> holder(rawHolder);
-      RefPtr<GMPParent> gmp = self->SelectPluginForAPI(nodeIdString, api, tags);
-      LOGD(("%s: %p returning %p for api %s", __FUNCTION__, (void *)self, (void *)gmp, api.get()));
-      if (!gmp) {
-        NS_WARNING("GeckoMediaPluginServiceParent::GetContentParentFrom failed");
-        holder->Reject(NS_ERROR_FAILURE, __func__);
-        return;
-      }
-      self->ConnectCrashHelper(gmp->GetPluginId(), helper);
-      gmp->GetGMPContentParent(Move(holder));
-    },
-    [rawHolder]() -> void {
-      UniquePtr<PromiseHolder> holder(rawHolder);
+  auto holder = MakeUnique<MozPromiseHolder<GetGMPContentParentPromise>>();
+  RefPtr<GetGMPContentParentPromise> promise = holder->Ensure(__func__);
+  EnsureInitialized()->Then(thread, __func__, [
+    self = RefPtr<GeckoMediaPluginServiceParent>(this),
+    nodeIdString = nsCString(aNodeIdString),
+    api = nsCString(aAPI),
+    tags = nsTArray<nsCString>(aTags),
+    helper = RefPtr<GMPCrashHelper>(aHelper),
+    holder = Move(holder)
+  ](const GenericPromise::ResolveOrRejectValue& aValue) mutable -> void {
+    if (aValue.IsReject()) {
       NS_WARNING("GMPService::EnsureInitialized failed.");
       holder->Reject(NS_ERROR_FAILURE, __func__);
-    });
+      return;
+    }
+    RefPtr<GMPParent> gmp = self->SelectPluginForAPI(nodeIdString, api, tags);
+    LOGD(("%s: %p returning %p for api %s",
+          __FUNCTION__,
+          self.get(),
+          gmp.get(),
+          api.get()));
+    if (!gmp) {
+      NS_WARNING("GeckoMediaPluginServiceParent::GetContentParentFrom failed");
+      holder->Reject(NS_ERROR_FAILURE, __func__);
+      return;
+    }
+    self->ConnectCrashHelper(gmp->GetPluginId(), helper);
+    gmp->GetGMPContentParent(Move(holder));
+  });
 
   return promise;
 }
 
 RefPtr<GetGMPContentParentPromise>
 GeckoMediaPluginServiceParent::GetContentParent(
   GMPCrashHelper* aHelper,
   const NodeId& aNodeId,