Bug 1288997 - AutoIPCStream DTOR must run after the use of the inputStream for PBlob, r=jld a=gchang
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 04 Oct 2016 09:19:04 +0200
changeset 356114 09b4ee752f1720c2782318f501f084bbe33175f8
parent 356113 4dc5626ae64fead3bf40f480a3b1fc9061daf997
child 356115 5e6651e32d271d35974a5eca2e898e7c354b8ea4
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjld, gchang
bugs1288997
milestone51.0a2
Bug 1288997 - AutoIPCStream DTOR must run after the use of the inputStream for PBlob, r=jld a=gchang
dom/base/nsHostObjectProtocolHandler.cpp
dom/ipc/Blob.cpp
--- a/dom/base/nsHostObjectProtocolHandler.cpp
+++ b/dom/base/nsHostObjectProtocolHandler.cpp
@@ -134,21 +134,16 @@ BroadcastBlobURLRegistration(const nsACS
   MOZ_ASSERT(aBlobImpl);
 
   if (XRE_IsParentProcess()) {
     ContentParent::BroadcastBlobURLRegistration(aURI, aBlobImpl,
                                                 aPrincipal);
     return;
   }
 
-  // We don't need to broadcast Blob URL if we have just 1 content process.
-  if (Preferences::GetInt("dom.ipc.processCount", 0) <= 1) {
-    return;
-  }
-
   ContentChild* cc = ContentChild::GetSingleton();
   BlobChild* actor = cc->GetOrCreateActorForBlobImpl(aBlobImpl);
   if (NS_WARN_IF(!actor)) {
     return;
   }
 
   Unused << NS_WARN_IF(!cc->SendStoreAndBroadcastBlobURLRegistration(
     nsCString(aURI), actor, IPC::Principal(aPrincipal)));
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -910,17 +910,18 @@ CreateBlobImpl(const ParentBlobConstruct
   RefPtr<BlobImpl> blobImpl =
     CreateBlobImplFromBlobData(aBlobData, metadata);
   return blobImpl.forget();
 }
 
 template <class ChildManagerType>
 void
 BlobDataFromBlobImpl(ChildManagerType* aManager, BlobImpl* aBlobImpl,
-                     BlobData& aBlobData)
+                     BlobData& aBlobData,
+                     nsTArray<UniquePtr<AutoIPCStream>>& aIPCStreams)
 {
   MOZ_ASSERT(gProcessType != GeckoProcessType_Default);
   MOZ_ASSERT(aBlobImpl);
 
   const nsTArray<RefPtr<BlobImpl>>* subBlobs = aBlobImpl->GetSubBlobImpls();
 
   if (subBlobs) {
     MOZ_ASSERT(subBlobs->Length());
@@ -929,17 +930,17 @@ BlobDataFromBlobImpl(ChildManagerType* a
 
     nsTArray<BlobData>& subBlobDatas = aBlobData.get_ArrayOfBlobData();
     subBlobDatas.SetLength(subBlobs->Length());
 
     for (uint32_t count = subBlobs->Length(), index = 0;
          index < count;
          index++) {
       BlobDataFromBlobImpl(aManager, subBlobs->ElementAt(index),
-                           subBlobDatas[index]);
+                           subBlobDatas[index], aIPCStreams);
     }
 
     return;
   }
 
   nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlobImpl);
   if (remoteBlob) {
     BlobChild* actor = remoteBlob->GetBlobChild();
@@ -949,19 +950,21 @@ BlobDataFromBlobImpl(ChildManagerType* a
     return;
   }
 
   ErrorResult rv;
   nsCOMPtr<nsIInputStream> inputStream;
   aBlobImpl->GetInternalStream(getter_AddRefs(inputStream), rv);
   MOZ_ALWAYS_TRUE(!rv.Failed());
 
-  AutoIPCStream autoStream;
-  autoStream.Serialize(inputStream, aManager);
-  aBlobData = autoStream.TakeValue();
+  UniquePtr<AutoIPCStream> autoStream(new AutoIPCStream());
+  autoStream->Serialize(inputStream, aManager);
+  aBlobData = autoStream->TakeValue();
+
+  aIPCStreams.AppendElement(Move(autoStream));
 }
 
 RemoteInputStream::RemoteInputStream(BlobImpl* aBlobImpl,
                                      uint64_t aStart,
                                      uint64_t aLength)
   : mMonitor("RemoteInputStream.mMonitor")
   , mActor(nullptr)
   , mBlobImpl(aBlobImpl)
@@ -3339,28 +3342,29 @@ BlobChild::GetOrCreateFromImpl(ChildMana
   if (NS_WARN_IF(NS_FAILED(aBlobImpl->SetMutable(false)))) {
     return nullptr;
   }
 
   MOZ_ASSERT(!aBlobImpl->IsSizeUnknown());
   MOZ_ASSERT(!aBlobImpl->IsDateUnknown());
 
   AnyBlobConstructorParams blobParams;
+  nsTArray<UniquePtr<AutoIPCStream>> autoIPCStreams;
 
   if (gProcessType == GeckoProcessType_Default) {
     RefPtr<BlobImpl> sameProcessImpl = aBlobImpl;
     auto addRefedBlobImpl =
       reinterpret_cast<intptr_t>(sameProcessImpl.forget().take());
 
     blobParams = SameProcessBlobConstructorParams(addRefedBlobImpl);
   } else {
     // BlobData is going to be populate here and it _must_ be send via IPC in
     // order to avoid leaks.
     BlobData blobData;
-    BlobDataFromBlobImpl(aManager, aBlobImpl, blobData);
+    BlobDataFromBlobImpl(aManager, aBlobImpl, blobData, autoIPCStreams);
 
     nsString contentType;
     aBlobImpl->GetType(contentType);
 
     ErrorResult rv;
     uint64_t length = aBlobImpl->GetSize(rv);
     MOZ_ASSERT(!rv.Failed());
 
@@ -3385,16 +3389,17 @@ BlobChild::GetOrCreateFromImpl(ChildMana
   BlobChild* actor = new BlobChild(aManager, aBlobImpl);
 
   ParentBlobConstructorParams params(blobParams);
 
   if (NS_WARN_IF(!aManager->SendPBlobConstructor(actor, params))) {
     return nullptr;
   }
 
+  autoIPCStreams.Clear();
   return actor;
 }
 
 // static
 template <class ChildManagerType>
 BlobChild*
 BlobChild::CreateFromParams(ChildManagerType* aManager,
                             const ChildBlobConstructorParams& aParams)