Bug 1288997 - memory blob should not be shared across processes - part 1 -PSendStream should use nsIContentChild, r=jld, f=bkelly
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 21 Sep 2016 12:27:26 +0200
changeset 314822 11eb7909e663f9fa08b207629157cfeef618e1ba
parent 314821 a1bbdaf0f9ca893783df6ec827b04e1ce18be3fc
child 314823 7fa97d6743774b16907a183d198b15f4e07d5fee
push id30735
push usercbook@mozilla.com
push dateThu, 22 Sep 2016 09:55:35 +0000
treeherdermozilla-central@f0e6cc636021 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjld
bugs1288997
milestone52.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 1288997 - memory blob should not be shared across processes - part 1 -PSendStream should use nsIContentChild, r=jld, f=bkelly
dom/fetch/InternalResponse.cpp
dom/flyweb/FlyWebPublishedServer.cpp
dom/ipc/ContentBridgeChild.cpp
dom/ipc/ContentBridgeChild.h
dom/ipc/ContentBridgeParent.cpp
dom/ipc/ContentBridgeParent.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/PContentBridge.ipdl
dom/ipc/nsIContentChild.cpp
dom/ipc/nsIContentChild.h
dom/ipc/nsIContentParent.cpp
dom/ipc/nsIContentParent.h
ipc/glue/FileDescriptorSetChild.h
ipc/glue/FileDescriptorSetParent.h
ipc/glue/IPCStreamUtils.cpp
ipc/glue/IPCStreamUtils.h
ipc/glue/PFileDescriptorSet.ipdl
ipc/glue/PSendStream.ipdl
ipc/glue/SendStream.h
ipc/glue/SendStreamChild.cpp
--- a/dom/fetch/InternalResponse.cpp
+++ b/dom/fetch/InternalResponse.cpp
@@ -80,19 +80,19 @@ InternalResponse::~InternalResponse()
 }
 
 template void
 InternalResponse::ToIPC<PContentParent>
   (IPCInternalResponse* aIPCResponse,
    PContentParent* aManager,
    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
 template void
-InternalResponse::ToIPC<PContentChild>
+InternalResponse::ToIPC<nsIContentChild>
   (IPCInternalResponse* aIPCResponse,
-   PContentChild* aManager,
+   nsIContentChild* aManager,
    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
 template void
 InternalResponse::ToIPC<mozilla::ipc::PBackgroundParent>
   (IPCInternalResponse* aIPCResponse,
    mozilla::ipc::PBackgroundParent* aManager,
    UniquePtr<mozilla::ipc::AutoIPCStream>& aAutoStream);
 template void
 InternalResponse::ToIPC<mozilla::ipc::PBackgroundChild>
--- a/dom/flyweb/FlyWebPublishedServer.cpp
+++ b/dom/flyweb/FlyWebPublishedServer.cpp
@@ -364,17 +364,18 @@ FlyWebPublishedServerChild::OnFetchRespo
   }
 
   uint64_t id = mPendingRequests.Get(aRequest);
   MOZ_ASSERT(id);
   mPendingRequests.Remove(aRequest);
 
   IPCInternalResponse ipcResp;
   UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
-  aResponse->ToIPC(&ipcResp, Manager(), autoStream);
+  nsIContentChild* cc = static_cast<ContentChild*>(Manager());
+  aResponse->ToIPC(&ipcResp, cc, autoStream);
   Unused << SendFetchResponse(ipcResp, id);
   if (autoStream) {
     autoStream->TakeOptionalValue();
   }
 }
 
 already_AddRefed<nsITransportProvider>
 FlyWebPublishedServerChild::OnWebSocketAcceptInternal(InternalRequest* aRequest,
@@ -430,17 +431,18 @@ FlyWebPublishedServerChild::OnWebSocketR
   uint64_t id = mPendingRequests.Get(aRequest);
   MOZ_ASSERT(id);
   mPendingRequests.Remove(aRequest);
 
   mPendingTransportProviders.Remove(id);
 
   IPCInternalResponse ipcResp;
   UniquePtr<mozilla::ipc::AutoIPCStream> autoStream;
-  aResponse->ToIPC(&ipcResp, Manager(), autoStream);
+  nsIContentChild* cc = static_cast<ContentChild*>(Manager());
+  aResponse->ToIPC(&ipcResp, cc, autoStream);
 
   Unused << SendWebSocketResponse(ipcResp, id);
   if (autoStream) {
     autoStream->TakeOptionalValue();
   }
 }
 
 void
--- a/dom/ipc/ContentBridgeChild.cpp
+++ b/dom/ipc/ContentBridgeChild.cpp
@@ -85,16 +85,28 @@ ContentBridgeChild::SendPBrowserConstruc
                                                       aTabId,
                                                       aContext,
                                                       aChromeFlags,
                                                       aCpID,
                                                       aIsForApp,
                                                       aIsForBrowser);
 }
 
+PFileDescriptorSetChild*
+ContentBridgeChild::SendPFileDescriptorSetConstructor(const FileDescriptor& aFD)
+{
+  return PContentBridgeChild::SendPFileDescriptorSetConstructor(aFD);
+}
+
+PSendStreamChild*
+ContentBridgeChild::SendPSendStreamConstructor(PSendStreamChild* aActor)
+{
+  return PContentBridgeChild::SendPSendStreamConstructor(aActor);
+}
+
 // This implementation is identical to ContentChild::GetCPOWManager but we can't
 // move it to nsIContentChild because it calls ManagedPJavaScriptChild() which
 // only exists in PContentChild and PContentBridgeChild.
 jsipc::CPOWManager*
 ContentBridgeChild::GetCPOWManager()
 {
   if (PJavaScriptChild* c = LoneManagedOrNullAsserts(ManagedPJavaScriptChild())) {
     return CPOWManagerFor(c);
@@ -161,10 +173,34 @@ ContentBridgeChild::AllocPBlobChild(cons
 }
 
 bool
 ContentBridgeChild::DeallocPBlobChild(PBlobChild* aActor)
 {
   return nsIContentChild::DeallocPBlobChild(aActor);
 }
 
+PSendStreamChild*
+ContentBridgeChild::AllocPSendStreamChild()
+{
+  return nsIContentChild::AllocPSendStreamChild();
+}
+
+bool
+ContentBridgeChild::DeallocPSendStreamChild(PSendStreamChild* aActor)
+{
+  return nsIContentChild::DeallocPSendStreamChild(aActor);
+}
+
+PFileDescriptorSetChild*
+ContentBridgeChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
+{
+  return nsIContentChild::AllocPFileDescriptorSetChild(aFD);
+}
+
+bool
+ContentBridgeChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
+{
+  return nsIContentChild::DeallocPFileDescriptorSetChild(aActor);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ContentBridgeChild.h
+++ b/dom/ipc/ContentBridgeChild.h
@@ -41,16 +41,22 @@ public:
   virtual bool SendPBrowserConstructor(PBrowserChild* aActor,
                                        const TabId& aTabId,
                                        const IPCTabContext& aContext,
                                        const uint32_t& aChromeFlags,
                                        const ContentParentId& aCpID,
                                        const bool& aIsForApp,
                                        const bool& aIsForBrowser) override;
 
+  virtual mozilla::ipc::PFileDescriptorSetChild*
+  SendPFileDescriptorSetConstructor(const mozilla::ipc::FileDescriptor&) override;
+
+  virtual mozilla::ipc::PSendStreamChild*
+  SendPSendStreamConstructor(mozilla::ipc::PSendStreamChild*) override;
+
   FORWARD_SHMEM_ALLOCATOR_TO(PContentBridgeChild)
 
 protected:
   virtual ~ContentBridgeChild();
 
   virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
                                             const IPCTabContext& aContext,
                                             const uint32_t& aChromeFlags,
@@ -67,16 +73,27 @@ protected:
                                        const bool& aIsForBrowser) override;
 
   virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() override;
   virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) override;
 
   virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams) override;
   virtual bool DeallocPBlobChild(PBlobChild*) override;
 
+  virtual mozilla::ipc::PSendStreamChild* AllocPSendStreamChild() override;
+
+  virtual bool
+  DeallocPSendStreamChild(mozilla::ipc::PSendStreamChild* aActor) override;
+
+  virtual PFileDescriptorSetChild*
+  AllocPFileDescriptorSetChild(const mozilla::ipc::FileDescriptor& aFD) override;
+
+  virtual bool
+  DeallocPFileDescriptorSetChild(mozilla::ipc::PFileDescriptorSetChild* aActor) override;
+
   DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeChild);
 
 protected: // members
   RefPtr<ContentBridgeChild> mSelfRef;
   Transport* mTransport; // owned
 };
 
 } // namespace dom
--- a/dom/ipc/ContentBridgeParent.cpp
+++ b/dom/ipc/ContentBridgeParent.cpp
@@ -188,10 +188,34 @@ ContentBridgeParent::Observe(nsISupports
                              const char16_t* aData)
 {
   if (!strcmp(aTopic, "content-child-shutdown")) {
     Close();
   }
   return NS_OK;
 }
 
+PFileDescriptorSetParent*
+ContentBridgeParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
+{
+  return nsIContentParent::AllocPFileDescriptorSetParent(aFD);
+}
+
+bool
+ContentBridgeParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
+{
+  return nsIContentParent::DeallocPFileDescriptorSetParent(aActor);
+}
+
+PSendStreamParent*
+ContentBridgeParent::AllocPSendStreamParent()
+{
+  return nsIContentParent::AllocPSendStreamParent();
+}
+
+bool
+ContentBridgeParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
+{
+  return nsIContentParent::DeallocPSendStreamParent(aActor);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/ipc/ContentBridgeParent.h
+++ b/dom/ipc/ContentBridgeParent.h
@@ -120,16 +120,26 @@ protected:
 
   virtual bool DeallocPBrowserParent(PBrowserParent*) override;
 
   virtual PBlobParent*
   AllocPBlobParent(const BlobConstructorParams& aParams) override;
 
   virtual bool DeallocPBlobParent(PBlobParent*) override;
 
+  virtual PSendStreamParent* AllocPSendStreamParent() override;
+
+  virtual bool DeallocPSendStreamParent(PSendStreamParent* aActor) override;
+
+  virtual PFileDescriptorSetParent*
+  AllocPFileDescriptorSetParent(const mozilla::ipc::FileDescriptor&) override;
+
+  virtual bool
+  DeallocPFileDescriptorSetParent(PFileDescriptorSetParent*) override;
+
   DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeParent);
 
 protected: // members
   RefPtr<ContentBridgeParent> mSelfRef;
   Transport* mTransport; // owned
   ContentParentId mChildID;
   bool mIsForApp;
   bool mIsForBrowser;
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1570,26 +1570,31 @@ ContentChild::RecvPBrowserConstructor(PB
 
 void
 ContentChild::GetAvailableDictionaries(InfallibleTArray<nsString>& aDictionaries)
 {
   aDictionaries = mAvailableDictionaries;
 }
 
 PFileDescriptorSetChild*
+ContentChild::SendPFileDescriptorSetConstructor(const FileDescriptor& aFD)
+{
+  return PContentChild::SendPFileDescriptorSetConstructor(aFD);
+}
+
+PFileDescriptorSetChild*
 ContentChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
 {
-  return new FileDescriptorSetChild(aFD);
+  return nsIContentChild::AllocPFileDescriptorSetChild(aFD);
 }
 
 bool
 ContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
 {
-  delete static_cast<FileDescriptorSetChild*>(aActor);
-  return true;
+  return nsIContentChild::DeallocPFileDescriptorSetChild(aActor);
 }
 
 bool
 ContentChild::DeallocPBrowserChild(PBrowserChild* aIframe)
 {
   return nsIContentChild::DeallocPBrowserChild(aIframe);
 }
 
@@ -1878,26 +1883,31 @@ ContentChild::AllocPPrintingChild()
 
 bool
 ContentChild::DeallocPPrintingChild(PPrintingChild* printing)
 {
   return true;
 }
 
 PSendStreamChild*
+ContentChild::SendPSendStreamConstructor(PSendStreamChild* aActor)
+{
+  return PContentChild::SendPSendStreamConstructor(aActor);
+}
+
+PSendStreamChild*
 ContentChild::AllocPSendStreamChild()
 {
-  MOZ_CRASH("PSendStreamChild actors should be manually constructed!");
+  return nsIContentChild::AllocPSendStreamChild();
 }
 
 bool
 ContentChild::DeallocPSendStreamChild(PSendStreamChild* aActor)
 {
-  delete aActor;
-  return true;
+  return nsIContentChild::DeallocPSendStreamChild(aActor);
 }
 
 PScreenManagerChild*
 ContentChild::AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
                                        float* aSystemDefaultScale,
                                        bool* aSuccess)
 {
   // The ContentParent should never attempt to allocate the
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -31,17 +31,16 @@ struct SubstitutionMapping;
 struct OverrideMapping;
 class nsIDomainPolicy;
 
 namespace mozilla {
 class RemoteSpellcheckEngineChild;
 
 namespace ipc {
 class OptionalURIParams;
-class PFileDescriptorSetChild;
 class URIParams;
 }// namespace ipc
 
 namespace dom {
 
 class AlertObserver;
 class ConsoleListener;
 class PStorageChild;
@@ -49,16 +48,17 @@ class ClonedMessageData;
 class TabChild;
 class GetFilesHelperChild;
 
 class ContentChild final : public PContentChild
                          , public nsIWindowProvider
                          , public nsIContentChild
 {
   typedef mozilla::dom::ClonedMessageData ClonedMessageData;
+  typedef mozilla::ipc::FileDescriptor FileDescriptor;
   typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
   typedef mozilla::ipc::PFileDescriptorSetChild PFileDescriptorSetChild;
   typedef mozilla::ipc::URIParams URIParams;
 
 public:
   NS_DECL_NSIWINDOWPROVIDER
 
   ContentChild();
@@ -293,16 +293,19 @@ public:
   virtual PNeckoChild* AllocPNeckoChild() override;
 
   virtual bool DeallocPNeckoChild(PNeckoChild*) override;
 
   virtual PPrintingChild* AllocPPrintingChild() override;
 
   virtual bool DeallocPPrintingChild(PPrintingChild*) override;
 
+  virtual PSendStreamChild*
+  SendPSendStreamConstructor(PSendStreamChild*) override;
+
   virtual PSendStreamChild* AllocPSendStreamChild() override;
   virtual bool DeallocPSendStreamChild(PSendStreamChild*) override;
 
   virtual PScreenManagerChild*
   AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
                            float* aSystemDefaultScale,
                            bool* aSuccess) override;
 
@@ -585,16 +588,19 @@ public:
   bool IsForApp() const { return mIsForApp; }
   bool IsForBrowser() const { return mIsForBrowser; }
 
   virtual PBlobChild*
   SendPBlobConstructor(PBlobChild* actor,
                        const BlobConstructorParams& params) override;
 
   virtual PFileDescriptorSetChild*
+  SendPFileDescriptorSetConstructor(const FileDescriptor&) override;
+
+  virtual PFileDescriptorSetChild*
   AllocPFileDescriptorSetChild(const FileDescriptor&) override;
 
   virtual bool
   DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) override;
 
   virtual bool SendPBrowserConstructor(PBrowserChild* actor,
                                        const TabId& aTabId,
                                        const IPCTabContext& context,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -73,21 +73,18 @@
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/dom/voicemail/VoicemailParent.h"
 #include "mozilla/embedding/printingui/PrintingParent.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/gfx/GPUProcessManager.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
-#include "mozilla/ipc/FileDescriptorSetParent.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
-#include "mozilla/ipc/PFileDescriptorSetParent.h"
 #include "mozilla/ipc/PSendStreamParent.h"
-#include "mozilla/ipc/SendStreamAlloc.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
 #include "mozilla/layers/PAPZParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/ImageBridgeParent.h"
 #include "mozilla/layers/LayerTreeOwnerTracker.h"
 #include "mozilla/layers/SharedBufferManagerParent.h"
@@ -3383,24 +3380,23 @@ ContentParent::GetPrintingParent()
   RefPtr<embedding::PrintingParent> printingParent = mPrintingParent;
   return printingParent.forget();
 }
 #endif
 
 PSendStreamParent*
 ContentParent::AllocPSendStreamParent()
 {
-  return mozilla::ipc::AllocPSendStreamParent();
+  return nsIContentParent::AllocPSendStreamParent();
 }
 
 bool
 ContentParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
 {
-  delete aActor;
-  return true;
+  return nsIContentParent::DeallocPSendStreamParent(aActor);
 }
 
 PScreenManagerParent*
 ContentParent::AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
                                          float* aSystemDefaultScale,
                                          bool* aSuccess)
 {
   return new ScreenManagerParent(aNumberOfScreens, aSystemDefaultScale, aSuccess);
@@ -4597,24 +4593,23 @@ ContentParent::RecvKeygenProvideContent(
   formProcessor->ProvideContent(NS_LITERAL_STRING("SELECT"), *aContent,
                                 *aAttribute);
   return true;
 }
 
 PFileDescriptorSetParent*
 ContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
 {
-  return new FileDescriptorSetParent(aFD);
+  return nsIContentParent::AllocPFileDescriptorSetParent(aFD);
 }
 
 bool
 ContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
 {
-  delete static_cast<FileDescriptorSetParent*>(aActor);
-  return true;
+  return nsIContentParent::DeallocPFileDescriptorSetParent(aActor);
 }
 
 bool
 ContentParent::IgnoreIPCPrincipal()
 {
   static bool sDidAddVarCache = false;
   static bool sIgnoreIPCPrincipal = false;
   if (!sDidAddVarCache) {
--- a/dom/ipc/PContentBridge.ipdl
+++ b/dom/ipc/PContentBridge.ipdl
@@ -3,16 +3,18 @@
 /* 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 PBlob;
 include protocol PBrowser;
 include protocol PContent;
 include protocol PJavaScript;
+include protocol PFileDescriptorSet;
+include protocol PSendStream;
 
 include DOMTypes;
 include JavaScriptTypes;
 include PTabContext;
 
 using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
 using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
 using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
@@ -31,30 +33,37 @@ namespace dom {
  * share PBrowsers and send messages to each other.
  */
 prio(normal upto urgent) sync protocol PContentBridge
 {
     bridges PContent, PContent;
 
     manages PBlob;
     manages PBrowser;
+    manages PFileDescriptorSet;
     manages PJavaScript;
+    manages PSendStream;
 
 parent:
     sync SyncMessage(nsString aMessage, ClonedMessageData aData,
                      CpowEntry[] aCpows, Principal aPrincipal)
       returns (StructuredCloneData[] retval);
 
     async PJavaScript();
+
+    async PSendStream();
+
 both:
     // Both the parent and the child can construct the PBrowser.
     // See the comment in PContent::PBrowser().
     async PBrowser(TabId tabId, IPCTabContext context, uint32_t chromeFlags,
                    ContentParentId cpId, bool isForApp, bool isForBrowser);
 
     async PBlob(BlobConstructorParams params);
 
+    async PFileDescriptorSet(FileDescriptor fd);
+
     async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
                        Principal aPrincipal, ClonedMessageData aData);
 };
 
 }
 }
--- a/dom/ipc/nsIContentChild.cpp
+++ b/dom/ipc/nsIContentChild.cpp
@@ -8,17 +8,19 @@
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/DOMTypes.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/ipc/BlobChild.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
+#include "mozilla/ipc/FileDescriptorSetChild.h"
 #include "mozilla/ipc/InputStreamUtils.h"
+#include "mozilla/ipc/SendStream.h"
 
 #include "nsPrintfCString.h"
 #include "xpcpublic.h"
 
 using namespace mozilla::ipc;
 using namespace mozilla::jsipc;
 
 namespace mozilla {
@@ -104,16 +106,42 @@ nsIContentChild::GetOrCreateActorForBlob
   MOZ_ASSERT(aImpl);
 
   BlobChild* actor = BlobChild::GetOrCreate(this, aImpl);
   NS_ENSURE_TRUE(actor, nullptr);
 
   return actor;
 }
 
+PSendStreamChild*
+nsIContentChild::AllocPSendStreamChild()
+{
+  MOZ_CRASH("PSendStreamChild actors should be manually constructed!");
+}
+
+bool
+nsIContentChild::DeallocPSendStreamChild(PSendStreamChild* aActor)
+{
+  delete aActor;
+  return true;
+}
+
+PFileDescriptorSetChild*
+nsIContentChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
+{
+  return new FileDescriptorSetChild(aFD);
+}
+
+bool
+nsIContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
+{
+  delete static_cast<FileDescriptorSetChild*>(aActor);
+  return true;
+}
+
 bool
 nsIContentChild::RecvAsyncMessage(const nsString& aMsg,
                                   InfallibleTArray<CpowEntry>&& aCpows,
                                   const IPC::Principal& aPrincipal,
                                   const ClonedMessageData& aData)
 {
   RefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::GetChildProcessManager();
   if (cpm) {
--- a/dom/ipc/nsIContentChild.h
+++ b/dom/ipc/nsIContentChild.h
@@ -22,16 +22,19 @@
 class nsString;
 
 namespace IPC {
 class Principal;
 } // namespace IPC
 
 namespace mozilla {
 namespace ipc {
+class FileDescriptor;
+class PFileDescriptorSetChild;
+class PSendStreamChild;
 class Shmem;
 } // namespace ipc
 
 namespace jsipc {
 class PJavaScriptChild;
 class CpowEntry;
 } // namespace jsipc
 
@@ -64,32 +67,48 @@ public:
   SendPBrowserConstructor(PBrowserChild* aActor,
                           const TabId& aTabId,
                           const IPCTabContext& aContext,
                           const uint32_t& aChromeFlags,
                           const ContentParentId& aCpID,
                           const bool& aIsForApp,
                           const bool& aIsForBrowser) = 0;
 
+  virtual mozilla::ipc::PFileDescriptorSetChild*
+  SendPFileDescriptorSetConstructor(const mozilla::ipc::FileDescriptor&) = 0;
+
+  virtual mozilla::ipc::PSendStreamChild*
+  SendPSendStreamConstructor(mozilla::ipc::PSendStreamChild*) = 0;
+
 protected:
   virtual jsipc::PJavaScriptChild* AllocPJavaScriptChild();
   virtual bool DeallocPJavaScriptChild(jsipc::PJavaScriptChild*);
 
   virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
                                             const IPCTabContext& aContext,
                                             const uint32_t& aChromeFlags,
                                             const ContentParentId& aCpId,
                                             const bool& aIsForApp,
                                             const bool& aIsForBrowser);
   virtual bool DeallocPBrowserChild(PBrowserChild*);
 
   virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams);
 
   virtual bool DeallocPBlobChild(PBlobChild* aActor);
 
+  virtual mozilla::ipc::PSendStreamChild* AllocPSendStreamChild();
+
+  virtual bool DeallocPSendStreamChild(mozilla::ipc::PSendStreamChild* aActor);
+
+  virtual mozilla::ipc::PFileDescriptorSetChild*
+  AllocPFileDescriptorSetChild(const mozilla::ipc::FileDescriptor& aFD);
+
+  virtual bool
+  DeallocPFileDescriptorSetChild(mozilla::ipc::PFileDescriptorSetChild* aActor);
+
   virtual bool RecvAsyncMessage(const nsString& aMsg,
                                 InfallibleTArray<jsipc::CpowEntry>&& aCpows,
                                 const IPC::Principal& aPrincipal,
                                 const ClonedMessageData& aData);
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentChild, NS_ICONTENTCHILD_IID)
 
--- a/dom/ipc/nsIContentParent.cpp
+++ b/dom/ipc/nsIContentParent.cpp
@@ -12,16 +12,19 @@
 #include "mozilla/dom/ContentParent.h"
 #include "mozilla/dom/ContentBridgeParent.h"
 #include "mozilla/dom/PTabContext.h"
 #include "mozilla/dom/PermissionMessageUtils.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/dom/ipc/BlobParent.h"
 #include "mozilla/dom/ipc/StructuredCloneData.h"
 #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
+#include "mozilla/ipc/FileDescriptorSetParent.h"
+#include "mozilla/ipc/PFileDescriptorSetParent.h"
+#include "mozilla/ipc/SendStreamAlloc.h"
 #include "mozilla/Unused.h"
 
 #include "nsFrameMessageManager.h"
 #include "nsIWebBrowserChrome.h"
 #include "nsPrintfCString.h"
 #include "xpcpublic.h"
 
 using namespace mozilla::jsipc;
@@ -262,16 +265,42 @@ nsIContentParent::RecvRpcMessage(const n
 
     CrossProcessCpowHolder cpows(this, aCpows);
     ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
                         aMsg, true, &data, &cpows, aPrincipal, aRetvals);
   }
   return true;
 }
 
+PFileDescriptorSetParent*
+nsIContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
+{
+  return new FileDescriptorSetParent(aFD);
+}
+
+bool
+nsIContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
+{
+  delete static_cast<FileDescriptorSetParent*>(aActor);
+  return true;
+}
+
+PSendStreamParent*
+nsIContentParent::AllocPSendStreamParent()
+{
+  return mozilla::ipc::AllocPSendStreamParent();
+}
+
+bool
+nsIContentParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
+{
+  delete aActor;
+  return true;
+}
+
 bool
 nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
                                    InfallibleTArray<CpowEntry>&& aCpows,
                                    const IPC::Principal& aPrincipal,
                                    const ClonedMessageData& aData)
 {
   // FIXME Permission check in Content process
   nsIPrincipal* principal = aPrincipal;
--- a/dom/ipc/nsIContentParent.h
+++ b/dom/ipc/nsIContentParent.h
@@ -25,16 +25,21 @@ class Principal;
 
 namespace mozilla {
 
 namespace jsipc {
 class PJavaScriptParent;
 class CpowEntry;
 } // namespace jsipc
 
+namespace ipc {
+class PFileDescriptorSetParent;
+class PSendStreamParent;
+}
+
 namespace dom {
 
 class Blob;
 class BlobConstructorParams;
 class BlobImpl;
 class BlobParent;
 class ContentParent;
 class ContentBridgeParent;
@@ -98,16 +103,26 @@ protected: // IPDL methods
                                               const bool& aIsForApp,
                                               const bool& aIsForBrowser);
   virtual bool DeallocPBrowserParent(PBrowserParent* frame);
 
   virtual PBlobParent* AllocPBlobParent(const BlobConstructorParams& aParams);
 
   virtual bool DeallocPBlobParent(PBlobParent* aActor);
 
+  virtual mozilla::ipc::PFileDescriptorSetParent*
+  AllocPFileDescriptorSetParent(const mozilla::ipc::FileDescriptor& aFD);
+
+  virtual bool
+  DeallocPFileDescriptorSetParent(mozilla::ipc::PFileDescriptorSetParent* aActor);
+
+  virtual mozilla::ipc::PSendStreamParent* AllocPSendStreamParent();
+
+  virtual bool DeallocPSendStreamParent(mozilla::ipc::PSendStreamParent* aActor);
+
   virtual bool RecvSyncMessage(const nsString& aMsg,
                                const ClonedMessageData& aData,
                                InfallibleTArray<jsipc::CpowEntry>&& aCpows,
                                const IPC::Principal& aPrincipal,
                                nsTArray<ipc::StructuredCloneData>* aRetvals);
   virtual bool RecvRpcMessage(const nsString& aMsg,
                               const ClonedMessageData& aData,
                               InfallibleTArray<jsipc::CpowEntry>&& aCpows,
--- a/ipc/glue/FileDescriptorSetChild.h
+++ b/ipc/glue/FileDescriptorSetChild.h
@@ -11,30 +11,30 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/ipc/PFileDescriptorSetChild.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 
 namespace dom {
 
-class ContentChild;
+class nsIContentChild;
 
 } // namespace dom
 
 namespace ipc {
 
 class BackgroundChildImpl;
 class FileDescriptor;
 
 class FileDescriptorSetChild final
   : public PFileDescriptorSetChild
 {
   friend class BackgroundChildImpl;
-  friend class mozilla::dom::ContentChild;
+  friend class mozilla::dom::nsIContentChild;
 
   nsTArray<FileDescriptor> mFileDescriptors;
 
 public:
   void
   ForgetFileDescriptors(nsTArray<FileDescriptor>& aFileDescriptors);
 
 private:
--- a/ipc/glue/FileDescriptorSetParent.h
+++ b/ipc/glue/FileDescriptorSetParent.h
@@ -11,30 +11,30 @@
 #include "mozilla/Attributes.h"
 #include "mozilla/ipc/PFileDescriptorSetParent.h"
 #include "nsTArray.h"
 
 namespace mozilla {
 
 namespace dom {
 
-class ContentParent;
+class nsIContentParent;
 
 } // namespace dom
 
 namespace ipc {
 
 class BackgroundParentImpl;
 class FileDescriptor;
 
 class FileDescriptorSetParent final
   : public PFileDescriptorSetParent
 {
   friend class BackgroundParentImpl;
-  friend class mozilla::dom::ContentParent;
+  friend class mozilla::dom::nsIContentParent;
 
   nsTArray<FileDescriptor> mFileDescriptors;
 
 public:
   void
   ForgetFileDescriptors(nsTArray<FileDescriptor>& aFileDescriptors);
 
 private:
--- a/ipc/glue/IPCStreamUtils.cpp
+++ b/ipc/glue/IPCStreamUtils.cpp
@@ -4,17 +4,17 @@
  * 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 "IPCStreamUtils.h"
 
 #include "nsIIPCSerializableInputStream.h"
 
 #include "mozilla/Assertions.h"
-#include "mozilla/dom/PContentChild.h"
+#include "mozilla/dom/nsIContentChild.h"
 #include "mozilla/dom/PContentParent.h"
 #include "mozilla/dom/File.h"
 #include "mozilla/ipc/FileDescriptorSetChild.h"
 #include "mozilla/ipc/FileDescriptorSetParent.h"
 #include "mozilla/ipc/InputStreamUtils.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "mozilla/ipc/PBackgroundParent.h"
 #include "mozilla/ipc/SendStream.h"
@@ -344,17 +344,17 @@ AutoIPCStream::~AutoIPCStream()
   if (mValue && IsSet()) {
     CleanupIPCStream(*mValue, mTaken);
   } else {
     CleanupIPCStream(*mOptionalValue, mTaken);
   }
 }
 
 void
-AutoIPCStream::Serialize(nsIInputStream* aStream, dom::PContentChild* aManager)
+AutoIPCStream::Serialize(nsIInputStream* aStream, dom::nsIContentChild* aManager)
 {
   MOZ_ASSERT(aStream);
   MOZ_ASSERT(aManager);
   MOZ_ASSERT(mValue || mOptionalValue);
   MOZ_ASSERT(!mTaken);
   MOZ_ASSERT(!IsSet());
 
   if (mValue) {
--- a/ipc/glue/IPCStreamUtils.h
+++ b/ipc/glue/IPCStreamUtils.h
@@ -8,17 +8,17 @@
 #define mozilla_ipc_IPCStreamUtils_h
 
 #include "mozilla/ipc/IPCStream.h"
 #include "nsIInputStream.h"
 
 namespace mozilla {
 
 namespace dom {
-class PContentChild;
+class nsIContentChild;
 class PContentParent;
 }
 
 namespace ipc {
 
 class PBackgroundChild;
 class PBackgroundParent;
 
@@ -142,17 +142,17 @@ public:
   explicit AutoIPCStream(OptionalIPCStream& aTarget);
 
   ~AutoIPCStream();
 
   // Serialize the input stream or create a SendStream actor using the PContent
   // manager.  If neither of these succeed, then crash.  This should only be
   // used on the main thread.
   void
-  Serialize(nsIInputStream* aStream, dom::PContentChild* aManager);
+  Serialize(nsIInputStream* aStream, dom::nsIContentChild* aManager);
 
   // Serialize the input stream or create a SendStream actor using the
   // PBackground manager.  If neither of these succeed, then crash.  This can
   // be called on the main thread or Worker threads.
   void
   Serialize(nsIInputStream* aStream, PBackgroundChild* aManager);
 
   // Serialize the input stream.  A PSendStream cannot be used when going
--- a/ipc/glue/PFileDescriptorSet.ipdl
+++ b/ipc/glue/PFileDescriptorSet.ipdl
@@ -1,21 +1,22 @@
 /* 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 protocol PContent;
+include protocol PContentBridge;
 
 namespace mozilla {
 namespace ipc {
 
 protocol PFileDescriptorSet
 {
-  manager PBackground or PContent;
+  manager PBackground or PContent or PContentBridge;
 
 both:
   async AddFileDescriptor(FileDescriptor fd);
 
   async __delete__();
 };
 
 } // namespace ipc
--- a/ipc/glue/PSendStream.ipdl
+++ b/ipc/glue/PSendStream.ipdl
@@ -1,21 +1,22 @@
 /* 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 protocol PContent;
+include protocol PContentBridge;
 
 namespace mozilla {
 namespace ipc {
 
 protocol PSendStream
 {
-  manager PBackground or PContent;
+  manager PBackground or PContent or PContentBridge;
 
 parent:
   async Buffer(nsCString aBuffer);
   async Close(nsresult aRv);
 
 child:
   // The parent side has hit an error condition and has requested the child
   // actor issue a Close() message.  The close must be initiated by the child
--- a/ipc/glue/SendStream.h
+++ b/ipc/glue/SendStream.h
@@ -12,17 +12,17 @@
 #include "mozilla/ipc/PSendStreamParent.h"
 
 class nsIInputStream;
 class nsIAsyncInputStream;
 
 namespace mozilla {
 
 namespace dom {
-class PContentChild;
+class nsIContentChild;
 } // dom namespace
 
 namespace ipc {
 
 class PBackgroundChild;
 
 // The SendStream IPC actor is designed to push an nsIInputStream from child to
 // parent incrementally.  This is mainly needed for streams such as nsPipe that
@@ -51,17 +51,17 @@ class PBackgroundChild;
 // defined in InputStreamUtils.h instead of using SendStreamChild directly.
 class SendStreamChild : public PSendStreamChild
 {
 public:
   // Create a SendStreamChild using a PContent IPC manager on the
   // main thread.  This can return nullptr if the provided stream is
   // blocking.
   static SendStreamChild*
-  Create(nsIAsyncInputStream* aInputStream, dom::PContentChild* aManager);
+  Create(nsIAsyncInputStream* aInputStream, dom::nsIContentChild* aManager);
 
   // Create a SendStreamChild using a PBackground IPC manager on the
   // main thread or a Worker thread.  This can return nullptr if the provided
   // stream is blocking or if the Worker thread is already shutting down.
   static SendStreamChild*
   Create(nsIAsyncInputStream* aInputStream, PBackgroundChild* aManager);
 
   // Start reading data from the nsIAsyncInputStream used to create the actor.
--- a/ipc/glue/SendStreamChild.cpp
+++ b/ipc/glue/SendStreamChild.cpp
@@ -2,30 +2,30 @@
 /* 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 "mozilla/ipc/SendStream.h"
 
 #include "mozilla/Unused.h"
-#include "mozilla/dom/PContentChild.h"
+#include "mozilla/dom/nsIContentChild.h"
 #include "mozilla/dom/WorkerPrivate.h"
 #include "mozilla/dom/workers/bindings/WorkerHolder.h"
 #include "mozilla/ipc/PBackgroundChild.h"
 #include "nsIAsyncInputStream.h"
 #include "nsICancelableRunnable.h"
 #include "nsIRunnable.h"
 #include "nsIThread.h"
 #include "nsStreamUtils.h"
 
 namespace mozilla {
 namespace ipc {
 
-using mozilla::dom::PContentChild;
+using mozilla::dom::nsIContentChild;
 using mozilla::dom::workers::Canceling;
 using mozilla::dom::workers::GetCurrentThreadWorkerPrivate;
 using mozilla::dom::workers::Status;
 using mozilla::dom::workers::WorkerHolder;
 using mozilla::dom::workers::WorkerPrivate;
 
 namespace {
 
@@ -354,17 +354,17 @@ IsBlocking(nsIAsyncInputStream* aInputSt
   return !nonBlocking;
 }
 
 } // anonymous namespace
 
 // static
 SendStreamChild*
 SendStreamChild::Create(nsIAsyncInputStream* aInputStream,
-                        PContentChild* aManager)
+                        nsIContentChild* aManager)
 {
   MOZ_ASSERT(aInputStream);
   MOZ_ASSERT(aManager);
 
   // PContent can only be used on the main thread
   MOZ_ASSERT(NS_IsMainThread());
 
   // SendStreamChild reads in the current thread, so it is only supported