Bug 1359087 - Use IPCBlob in FileHandle - part 1 - PPendingIPCBlob protocol, r=janv
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 09 May 2017 22:35:27 +0200
changeset 357433 9294be2d9f63c527304cd6f33a6ce73fa5d858a3
parent 357432 4dc76bc01b76f20f11661cfa12ef3dc275ad622f
child 357434 66fafc2b84cf145190468eee4e08de99e5934ad6
push id31792
push usercbook@mozilla.com
push dateWed, 10 May 2017 13:07:59 +0000
treeherdermozilla-central@ebbcdaa5b580 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjanv
bugs1359087
milestone55.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 1359087 - Use IPCBlob in FileHandle - part 1 - PPendingIPCBlob protocol, r=janv
dom/file/ipc/PPendingIPCBlob.ipdl
dom/file/ipc/PendingIPCBlobChild.cpp
dom/file/ipc/PendingIPCBlobChild.h
dom/file/ipc/PendingIPCBlobParent.cpp
dom/file/ipc/PendingIPCBlobParent.h
dom/file/ipc/moz.build
ipc/glue/BackgroundChildImpl.cpp
ipc/glue/BackgroundChildImpl.h
ipc/glue/BackgroundParentImpl.cpp
ipc/glue/BackgroundParentImpl.h
ipc/glue/PBackground.ipdl
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/PPendingIPCBlob.ipdl
@@ -0,0 +1,51 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+include protocol PBackground;
+
+include IPCBlob;
+
+namespace mozilla {
+namespace ipc {
+
+// IndexedDB and FileHandle do not know all the Blob/File properties when they
+// create a IPCBlob. For this reason, they need to use this simple protocol.
+// When the information is known, they send a __delete__ message with the
+// pending data.
+
+// This contains any extra bit for making a File out of a Blob.
+struct PendingIPCFileData
+{
+  nsString name;
+  int64_t lastModified;
+};
+
+// Union for blob vs file.
+union PendingIPCFileUnion
+{
+  // For Blob.
+  void_t;
+
+  // For File.
+  PendingIPCFileData;
+};
+
+struct PendingIPCBlobData
+{
+  nsString type;
+  uint64_t size;
+
+  PendingIPCFileUnion file;
+};
+
+protocol PPendingIPCBlob
+{
+  manager PBackground;
+
+parent:
+  async __delete__(PendingIPCBlobData aData);
+};
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/PendingIPCBlobChild.cpp
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "PendingIPCBlobChild.h"
+
+namespace mozilla {
+namespace dom {
+
+PendingIPCBlobChild::PendingIPCBlobChild(const IPCBlob& aBlob)
+{
+  mBlobImpl = IPCBlobUtils::Deserialize(aBlob);
+  MOZ_ASSERT(mBlobImpl);
+}
+
+PendingIPCBlobChild::~PendingIPCBlobChild()
+{}
+
+already_AddRefed<BlobImpl>
+PendingIPCBlobChild::SetPendingInfoAndDeleteActor(const nsString& aName,
+                                                  const nsString& aContentType,
+                                                  uint64_t aLength,
+                                                  int64_t aLastModifiedDate)
+{
+  RefPtr<BlobImpl> blobImpl;
+  blobImpl.swap(mBlobImpl);
+
+  blobImpl->SetLazyData(aName, aContentType, aLength, aLastModifiedDate);
+
+  PendingIPCFileData fileData(nsString(aName), aLastModifiedDate);
+  PendingIPCBlobData blobData(nsString(aContentType), aLength, fileData);
+  Unused << Send__delete__(this, blobData);
+
+  return blobImpl.forget();
+}
+
+already_AddRefed<BlobImpl>
+PendingIPCBlobChild::SetPendingInfoAndDeleteActor(const nsString& aContentType,
+                                                  uint64_t aLength)
+{
+  RefPtr<BlobImpl> blobImpl;
+  blobImpl.swap(mBlobImpl);
+
+  blobImpl->SetLazyData(NullString(), aContentType, aLength, INT64_MAX);
+
+  PendingIPCBlobData data(nsString(aContentType), aLength, void_t());
+  Unused << Send__delete__(this, data);
+
+  return blobImpl.forget();
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/PendingIPCBlobChild.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_ipc_PendingIPCBlobChild_h
+#define mozilla_dom_ipc_PendingIPCBlobChild_h
+
+#include "mozilla/ipc/PPendingIPCBlob.h"
+#include "mozilla/ipc/PPendingIPCBlobChild.h"
+
+namespace mozilla {
+namespace dom {
+
+class BlobImpl;
+
+class PendingIPCBlobChild final : public mozilla::ipc::PPendingIPCBlobChild
+{
+public:
+  explicit PendingIPCBlobChild(const IPCBlob& aBlob);
+
+  // After calling one of the following method, the actor will be deleted.
+
+  // For File.
+  already_AddRefed<BlobImpl>
+  SetPendingInfoAndDeleteActor(const nsString& aName,
+                               const nsString& aContentType,
+                               uint64_t aLength,
+                               int64_t aLastModifiedDate);
+
+  // For Blob.
+  already_AddRefed<BlobImpl>
+  SetPendingInfoAndDeleteActor(const nsString& aContentType,
+                               uint64_t aLength);
+
+private:
+  ~PendingIPCBlobChild();
+
+  RefPtr<BlobImpl> mBlobImpl;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ipc_PendingIPCBlobChild_h
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/PendingIPCBlobParent.cpp
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "PendingIPCBlobParent.h"
+
+namespace mozilla {
+
+using namespace ipc;
+
+namespace dom {
+
+/* static */
+PendingIPCBlobParent*
+PendingIPCBlobParent::Create(PBackgroundParent* aManager,
+                             BlobImpl* aBlobImpl)
+{
+  MOZ_ASSERT(aManager);
+  MOZ_ASSERT(aBlobImpl);
+
+  IPCBlob ipcBlob;
+  nsresult rv = IPCBlobUtils::Serialize(aBlobImpl, aManager, ipcBlob);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nullptr;
+  }
+
+  PendingIPCBlobParent* actor = new PendingIPCBlobParent(aBlobImpl);
+  if (!aManager->SendPPendingIPCBlobConstructor(actor, ipcBlob)) {
+    // The actor will be deleted by the manager.
+    return nullptr;
+  }
+
+  return actor;
+}
+
+PendingIPCBlobParent::PendingIPCBlobParent(BlobImpl* aBlobImpl)
+  : mBlobImpl(aBlobImpl)
+{}
+
+IPCResult
+PendingIPCBlobParent::Recv__delete__(const PendingIPCBlobData& aData)
+{
+  if (aData.file().type() == PendingIPCFileUnion::Tvoid_t) {
+    mBlobImpl->SetLazyData(NullString(), aData.type(), aData.size(), INT64_MAX);
+  } else {
+    const PendingIPCFileData& fileData =
+      aData.file().get_PendingIPCFileData();
+    mBlobImpl->SetLazyData(fileData.name(), aData.type(), aData.size(),
+                           fileData.lastModified());
+  }
+
+  return IPC_OK();
+}
+
+} // namespace dom
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/dom/file/ipc/PendingIPCBlobParent.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_ipc_PendingIPCBlobParent_h
+#define mozilla_dom_ipc_PendingIPCBlobParent_h
+
+#include "mozilla/ipc/PPendingIPCBlobParent.h"
+
+namespace mozilla {
+
+namespace ipc {
+class PBackgroundParent;
+}
+
+namespace dom {
+
+class BlobImpl;
+
+class PendingIPCBlobParent final : public mozilla::ipc::PPendingIPCBlobParent
+{
+public:
+  static PendingIPCBlobParent*
+  Create(PBackgroundParent* aManager, BlobImpl* aBlobImpl);
+
+  void
+  ActorDestroy(ActorDestroyReason aWhy) override
+  {}
+
+  mozilla::ipc::IPCResult
+  Recv__delete__(const PendingIPCBlobData& aData) override;
+
+private:
+  explicit PendingIPCBlobParent(BlobImpl* aBlobImpl);
+
+  RefPtr<BlobImpl> mBlobImpl;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+#endif // mozilla_dom_ipc_PendingIPCBlobParent_h
--- a/dom/file/ipc/moz.build
+++ b/dom/file/ipc/moz.build
@@ -9,39 +9,44 @@ EXPORTS.mozilla.dom.ipc += [
     'BlobParent.h',
     'IPCBlobInputStream.h',
     'IPCBlobInputStreamChild.h',
     'IPCBlobInputStreamParent.h',
     'IPCBlobInputStreamStorage.h',
     'MemoryStreamChild.h',
     'MemoryStreamParent.h',
     'nsIRemoteBlob.h',
+    'PendingIPCBlobChild.h',
+    'PendingIPCBlobParent.h',
 ]
 
 EXPORTS.mozilla.dom += [
     'IPCBlobUtils.h',
 ]
 
 UNIFIED_SOURCES += [
     'Blob.cpp',
     'IPCBlobInputStream.cpp',
     'IPCBlobInputStreamChild.cpp',
     'IPCBlobInputStreamParent.cpp',
     'IPCBlobInputStreamStorage.cpp',
     'IPCBlobUtils.cpp',
     'MemoryStreamParent.cpp',
+    'PendingIPCBlobChild.cpp',
+    'PendingIPCBlobParent.cpp',
 ]
 
 IPDL_SOURCES += [
     'BlobTypes.ipdlh',
     'IPCBlob.ipdlh',
     'PBlob.ipdl',
     'PBlobStream.ipdl',
     'PIPCBlobInputStream.ipdl',
     'PMemoryStream.ipdl',
+    'PPendingIPCBlob.ipdl',
 ]
 
 LOCAL_INCLUDES += [
     '/dom/file',
     '/dom/ipc',
     '/dom/workers',
 ]
 
--- a/ipc/glue/BackgroundChildImpl.cpp
+++ b/ipc/glue/BackgroundChildImpl.cpp
@@ -21,16 +21,17 @@
 #include "mozilla/dom/FileSystemTaskBase.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/PBackgroundIDBFactoryChild.h"
 #include "mozilla/dom/indexedDB/PBackgroundIndexedDBUtilsChild.h"
 #include "mozilla/dom/ipc/BlobChild.h"
 #include "mozilla/dom/ipc/IPCBlobInputStreamChild.h"
 #include "mozilla/dom/ipc/MemoryStreamChild.h"
+#include "mozilla/dom/ipc/PendingIPCBlobChild.h"
 #include "mozilla/dom/quota/PQuotaChild.h"
 #include "mozilla/dom/GamepadEventChannelChild.h"
 #include "mozilla/dom/GamepadTestChannelChild.h"
 #include "mozilla/dom/MessagePortChild.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/PBackgroundTestChild.h"
 #include "mozilla/ipc/PChildToParentStreamChild.h"
 #include "mozilla/ipc/PParentToChildStreamChild.h"
@@ -229,16 +230,29 @@ BackgroundChildImpl::AllocPMemoryStreamC
 
 bool
 BackgroundChildImpl::DeallocPMemoryStreamChild(PMemoryStreamChild* aActor)
 {
   delete aActor;
   return true;
 }
 
+PPendingIPCBlobChild*
+BackgroundChildImpl::AllocPPendingIPCBlobChild(const IPCBlob& aBlob)
+{
+  return new mozilla::dom::PendingIPCBlobChild(aBlob);
+}
+
+bool
+BackgroundChildImpl::DeallocPPendingIPCBlobChild(PPendingIPCBlobChild* aActor)
+{
+  delete aActor;
+  return true;
+}
+
 PIPCBlobInputStreamChild*
 BackgroundChildImpl::AllocPIPCBlobInputStreamChild(const nsID& aID,
                                                    const uint64_t& aSize)
 {
   // IPCBlobInputStreamChild is refcounted. Here it's created and in
   // DeallocPIPCBlobInputStreamChild is released.
 
   RefPtr<mozilla::dom::IPCBlobInputStreamChild> actor =
--- a/ipc/glue/BackgroundChildImpl.h
+++ b/ipc/glue/BackgroundChildImpl.h
@@ -77,16 +77,22 @@ protected:
   DeallocPBlobChild(PBlobChild* aActor) override;
 
   virtual PMemoryStreamChild*
   AllocPMemoryStreamChild(const uint64_t& aSize) override;
 
   virtual bool
   DeallocPMemoryStreamChild(PMemoryStreamChild* aActor) override;
 
+  virtual PPendingIPCBlobChild*
+  AllocPPendingIPCBlobChild(const IPCBlob& aBlob) override;
+
+  virtual bool
+  DeallocPPendingIPCBlobChild(PPendingIPCBlobChild* aActor) override;
+
   virtual PIPCBlobInputStreamChild*
   AllocPIPCBlobInputStreamChild(const nsID& aID,
                                 const uint64_t& aSize) override;
 
   virtual bool
   DeallocPIPCBlobInputStreamChild(PIPCBlobInputStreamChild* aActor) override;
 
   virtual PFileDescriptorSetChild*
--- a/ipc/glue/BackgroundParentImpl.cpp
+++ b/ipc/glue/BackgroundParentImpl.cpp
@@ -25,16 +25,17 @@
 #include "mozilla/dom/MessagePortParent.h"
 #include "mozilla/dom/ServiceWorkerRegistrar.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/cache/ActorUtils.h"
 #include "mozilla/dom/indexedDB/ActorsParent.h"
 #include "mozilla/dom/ipc/BlobParent.h"
 #include "mozilla/dom/ipc/IPCBlobInputStreamParent.h"
 #include "mozilla/dom/ipc/MemoryStreamParent.h"
+#include "mozilla/dom/ipc/PendingIPCBlobParent.h"
 #include "mozilla/dom/quota/ActorsParent.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/BackgroundUtils.h"
 #include "mozilla/ipc/IPCStreamAlloc.h"
 #include "mozilla/ipc/PBackgroundSharedTypes.h"
 #include "mozilla/ipc/PBackgroundTestParent.h"
 #include "mozilla/ipc/PChildToParentStreamParent.h"
 #include "mozilla/ipc/PParentToChildStreamParent.h"
@@ -285,16 +286,33 @@ BackgroundParentImpl::DeallocPMemoryStre
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aActor);
 
   delete aActor;
   return true;
 }
 
+PPendingIPCBlobParent*
+BackgroundParentImpl::AllocPPendingIPCBlobParent(const IPCBlob& aBlob)
+{
+  MOZ_CRASH("PPendingIPCBlobParent actors should be manually constructed!");
+}
+
+bool
+BackgroundParentImpl::DeallocPPendingIPCBlobParent(PPendingIPCBlobParent* aActor)
+{
+  AssertIsInMainProcess();
+  AssertIsOnBackgroundThread();
+  MOZ_ASSERT(aActor);
+
+  delete aActor;
+  return true;
+}
+
 PIPCBlobInputStreamParent*
 BackgroundParentImpl::AllocPIPCBlobInputStreamParent(const nsID& aID,
                                                      const uint64_t& aSize)
 {
   MOZ_CRASH("PIPCBlobInputStreamParent actors should be manually constructed!");
 }
 
 bool
--- a/ipc/glue/BackgroundParentImpl.h
+++ b/ipc/glue/BackgroundParentImpl.h
@@ -70,16 +70,22 @@ protected:
   DeallocPBlobParent(PBlobParent* aActor) override;
 
   virtual PMemoryStreamParent*
   AllocPMemoryStreamParent(const uint64_t& aSize) override;
 
   virtual bool
   DeallocPMemoryStreamParent(PMemoryStreamParent* aActor) override;
 
+  virtual PPendingIPCBlobParent*
+  AllocPPendingIPCBlobParent(const IPCBlob& aBlob) override;
+
+  virtual bool
+  DeallocPPendingIPCBlobParent(PPendingIPCBlobParent* aActor) override;
+
   virtual PIPCBlobInputStreamParent*
   AllocPIPCBlobInputStreamParent(const nsID& aID,
                                  const uint64_t& aSize) override;
 
   virtual bool
   DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActor) override;
 
   virtual mozilla::ipc::IPCResult
--- a/ipc/glue/PBackground.ipdl
+++ b/ipc/glue/PBackground.ipdl
@@ -11,28 +11,30 @@ include protocol PBroadcastChannel;
 include protocol PCache;
 include protocol PCacheStorage;
 include protocol PCacheStreamControl;
 include protocol PFileDescriptorSet;
 include protocol PFileSystemRequest;
 include protocol PGamepadEventChannel;
 include protocol PGamepadTestChannel;
 include protocol PIPCBlobInputStream;
+include protocol PPendingIPCBlob;
 include protocol PMemoryStream;
 include protocol PMessagePort;
 include protocol PCameras;
 include protocol PQuota;
 include protocol PChildToParentStream;
 include protocol PParentToChildStream;
 include protocol PServiceWorkerManager;
 include protocol PWebAuthnTransaction;
 include protocol PUDPSocket;
 include protocol PVsync;
 
 include DOMTypes;
+include IPCBlob;
 include PBackgroundSharedTypes;
 include PBackgroundIDBSharedTypes;
 include PFileSystemParams;
 include ProtocolTypes;
 
 include "mozilla/dom/cache/IPCUtils.h";
 
 using mozilla::dom::cache::Namespace
@@ -59,16 +61,17 @@ sync protocol PBackground
   manages PCacheStorage;
   manages PCacheStreamControl;
   manages PFileDescriptorSet;
   manages PFileSystemRequest;
   manages PGamepadEventChannel;
   manages PGamepadTestChannel;
   manages PIPCBlobInputStream;
   manages PMemoryStream;
+  manages PPendingIPCBlob;
   manages PMessagePort;
   manages PCameras;
   manages PQuota;
   manages PChildToParentStream;
   manages PParentToChildStream;
   manages PServiceWorkerManager;
   manages PWebAuthnTransaction;
   manages PUDPSocket;
@@ -123,16 +126,18 @@ parent:
 child:
   async PCache();
   async PCacheStreamControl();
 
   async PParentToChildStream();
 
   async PIPCBlobInputStream(nsID aID, uint64_t aSize);
 
+  async PPendingIPCBlob(IPCBlob blob);
+
 both:
   async PBlob(BlobConstructorParams params);
 
   async PFileDescriptorSet(FileDescriptor fd);
 };
 
 } // namespace ipc
 } // namespace mozilla