Bug 1119878 Part 2: Change IPC code to hold ProcessID instead of ProcessHandle. r=billm, r=dvander, r=aklotz, r=cpearce
authorBob Owen <bobowencode@gmail.com>
Wed, 01 Apr 2015 09:40:35 +0100
changeset 268359 aee0f61516c53778dba9c97c6cbd5c35750902e3
parent 268358 6790a442f39a529638c2db31786cabf8ee313751
child 268360 339271da9ef5d528983194d3f6737ea75db2df91
push id863
push userraliiev@mozilla.com
push dateMon, 03 Aug 2015 13:22:43 +0000
treeherdermozilla-release@f6321b14228d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm, dvander, aklotz, cpearce
bugs1119878
milestone40.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 1119878 Part 2: Change IPC code to hold ProcessID instead of ProcessHandle. r=billm, r=dvander, r=aklotz, r=cpearce
dom/ipc/ContentBridgeChild.cpp
dom/ipc/ContentBridgeParent.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentProcess.cpp
dom/ipc/ContentProcess.h
dom/ipc/CrashReporterParent.h
dom/ipc/ProcessHangMonitor.cpp
dom/media/gmp/GMPChild.cpp
dom/media/gmp/GMPChild.h
dom/media/gmp/GMPParent.cpp
dom/media/gmp/GMPProcessChild.cpp
dom/media/gmp/GMPProcessChild.h
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/ipc/PluginModuleChild.h
dom/plugins/ipc/PluginModuleParent.cpp
dom/plugins/ipc/PluginProcessChild.cpp
dom/plugins/ipc/PluginProcessChild.h
gfx/ipc/SharedDIB.cpp
gfx/ipc/SharedDIB.h
gfx/ipc/SharedDIBSurface.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/ipc/CompositorChild.cpp
gfx/layers/ipc/CompositorParent.cpp
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/SharedBufferManagerChild.cpp
gfx/layers/ipc/SharedBufferManagerParent.cpp
ipc/chromium/src/base/process_util_win.cc
ipc/chromium/src/base/shared_memory.h
ipc/chromium/src/base/shared_memory_posix.cc
ipc/chromium/src/base/shared_memory_win.cc
ipc/glue/BackgroundImpl.cpp
ipc/glue/CrossProcessMutex.h
ipc/glue/CrossProcessMutex_posix.cpp
ipc/glue/CrossProcessMutex_unimplemented.cpp
ipc/glue/CrossProcessMutex_windows.cpp
ipc/glue/FileDescriptor.cpp
ipc/glue/FileDescriptor.h
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoChildProcessHost.h
ipc/glue/ProcessChild.cpp
ipc/glue/ProcessChild.h
ipc/glue/ProtocolUtils.cpp
ipc/glue/ProtocolUtils.h
ipc/glue/SharedMemoryBasic_android.cpp
ipc/glue/SharedMemoryBasic_android.h
ipc/glue/SharedMemoryBasic_chromium.h
ipc/glue/Shmem.cpp
ipc/glue/Shmem.h
ipc/glue/Transport.h
ipc/glue/Transport_posix.cpp
ipc/glue/Transport_win.cpp
ipc/glue/moz.build
ipc/ipdl/ipdl/lower.py
ipc/ipdl/test/cxx/IPDLUnitTestProcessChild.cpp
ipc/ipdl/test/cxx/IPDLUnitTestProcessChild.h
ipc/ipdl/test/cxx/IPDLUnitTests.h
ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp
security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
toolkit/xre/nsEmbedFunctions.cpp
widget/nsBaseWidget.cpp
--- a/dom/ipc/ContentBridgeChild.cpp
+++ b/dom/ipc/ContentBridgeChild.cpp
@@ -34,28 +34,23 @@ void
 ContentBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   MessageLoop::current()->PostTask(
     FROM_HERE,
     NewRunnableMethod(this, &ContentBridgeChild::DeferredDestroy));
 }
 
 /*static*/ ContentBridgeChild*
-ContentBridgeChild::Create(Transport* aTransport, ProcessId aOtherProcess)
+ContentBridgeChild::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   nsRefPtr<ContentBridgeChild> bridge =
     new ContentBridgeChild(aTransport);
-  ProcessHandle handle;
-  if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-    // XXX need to kill |aOtherProcess|, it's boned
-    return nullptr;
-  }
   bridge->mSelfRef = bridge;
 
-  DebugOnly<bool> ok = bridge->Open(aTransport, handle, XRE_GetIOMessageLoop());
+  DebugOnly<bool> ok = bridge->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop());
   MOZ_ASSERT(ok);
   return bridge;
 }
 
 void
 ContentBridgeChild::DeferredDestroy()
 {
   mSelfRef = nullptr;
--- a/dom/ipc/ContentBridgeParent.cpp
+++ b/dom/ipc/ContentBridgeParent.cpp
@@ -37,28 +37,24 @@ ContentBridgeParent::ActorDestroy(ActorD
     os->RemoveObserver(this, "content-child-shutdown");
   }
   MessageLoop::current()->PostTask(
     FROM_HERE,
     NewRunnableMethod(this, &ContentBridgeParent::DeferredDestroy));
 }
 
 /*static*/ ContentBridgeParent*
-ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherProcess)
+ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   nsRefPtr<ContentBridgeParent> bridge =
     new ContentBridgeParent(aTransport);
-  ProcessHandle handle;
-  if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-    // XXX need to kill |aOtherProcess|, it's boned
-    return nullptr;
-  }
   bridge->mSelfRef = bridge;
 
-  DebugOnly<bool> ok = bridge->Open(aTransport, handle, XRE_GetIOMessageLoop());
+  DebugOnly<bool> ok = bridge->Open(aTransport, aOtherPid,
+                                    XRE_GetIOMessageLoop());
   MOZ_ASSERT(ok);
 
   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   if (os) {
     os->AddObserver(bridge, "content-child-shutdown", false);
   }
 
   // Initialize the message manager (and load delayed scripts) now that we
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -602,17 +602,17 @@ ContentChild::~ContentChild()
 
 NS_INTERFACE_MAP_BEGIN(ContentChild)
   NS_INTERFACE_MAP_ENTRY(nsIContentChild)
   NS_INTERFACE_MAP_ENTRY(nsISupports)
 NS_INTERFACE_MAP_END
 
 bool
 ContentChild::Init(MessageLoop* aIOLoop,
-                   base::ProcessHandle aParentHandle,
+                   base::ProcessId aParentPid,
                    IPC::Channel* aChannel)
 {
 #ifdef MOZ_WIDGET_GTK
     // sigh
     gtk_init(nullptr, nullptr);
 #endif
 
 #ifdef MOZ_WIDGET_QT
@@ -634,17 +634,17 @@ ContentChild::Init(MessageLoop* aIOLoop,
     // Once we start sending IPC messages, we need the thread manager to be
     // initialized so we can deal with the responses. Do that here before we
     // try to construct the crash reporter.
     nsresult rv = nsThreadManager::get()->Init();
     if (NS_WARN_IF(NS_FAILED(rv))) {
         return false;
     }
 
-    if (!Open(aChannel, aParentHandle, aIOLoop)) {
+    if (!Open(aChannel, aParentPid, aIOLoop)) {
       return false;
     }
     sSingleton = this;
 
     // Make sure there's an nsAutoScriptBlocker on the stack when dispatching
     // urgent messages.
     GetIPCChannel()->BlockScripts();
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -73,17 +73,17 @@ public:
         nsCString buildID;
         nsCString name;
         nsCString UAName;
         nsCString ID;
         nsCString vendor;
     };
 
     bool Init(MessageLoop* aIOLoop,
-              base::ProcessHandle aParentHandle,
+              base::ProcessId aParentPid,
               IPC::Channel* aChannel);
     void InitProcessAttributes();
     void InitXPCOM();
 
     static ContentChild* GetSingleton() {
         return sSingleton;
     }
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1711,49 +1711,41 @@ ContentParent::OnBeginSyncTransaction() 
             NS_WARNING("Unsafe synchronous IPC message");
         }
     }
 }
 
 void
 ContentParent::OnChannelConnected(int32_t pid)
 {
-    ProcessHandle handle;
-    if (!base::OpenPrivilegedProcessHandle(pid, &handle)) {
-        NS_WARNING("Can't open handle to child process.");
-    }
-    else {
-        // we need to close the existing handle before setting a new one.
-        base::CloseProcessHandle(OtherProcess());
-        SetOtherProcess(handle);
+    SetOtherProcessId(pid);
 
 #if defined(ANDROID) || defined(LINUX)
-        // Check nice preference
-        int32_t nice = Preferences::GetInt("dom.ipc.content.nice", 0);
-
-        // Environment variable overrides preference
-        char* relativeNicenessStr = getenv("MOZ_CHILD_PROCESS_RELATIVE_NICENESS");
-        if (relativeNicenessStr) {
-            nice = atoi(relativeNicenessStr);
+    // Check nice preference
+    int32_t nice = Preferences::GetInt("dom.ipc.content.nice", 0);
+
+    // Environment variable overrides preference
+    char* relativeNicenessStr = getenv("MOZ_CHILD_PROCESS_RELATIVE_NICENESS");
+    if (relativeNicenessStr) {
+        nice = atoi(relativeNicenessStr);
+    }
+
+    /* make the GUI thread have higher priority on single-cpu devices */
+    nsCOMPtr<nsIPropertyBag2> infoService = do_GetService(NS_SYSTEMINFO_CONTRACTID);
+    if (infoService) {
+        int32_t cpus;
+        nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("cpucount"), &cpus);
+        if (NS_FAILED(rv)) {
+            cpus = 1;
         }
-
-        /* make the GUI thread have higher priority on single-cpu devices */
-        nsCOMPtr<nsIPropertyBag2> infoService = do_GetService(NS_SYSTEMINFO_CONTRACTID);
-        if (infoService) {
-            int32_t cpus;
-            nsresult rv = infoService->GetPropertyAsInt32(NS_LITERAL_STRING("cpucount"), &cpus);
-            if (NS_FAILED(rv)) {
-                cpus = 1;
-            }
-            if (nice != 0 && cpus == 1) {
-                setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid) + nice);
-            }
+        if (nice != 0 && cpus == 1) {
+            setpriority(PRIO_PROCESS, pid, getpriority(PRIO_PROCESS, pid) + nice);
         }
+    }
 #endif
-    }
 }
 
 void
 ContentParent::ProcessingError(Result aCode, const char* aReason)
 {
     if (MsgDropped == aCode) {
         return;
     }
@@ -2149,17 +2141,18 @@ ContentParent::ContentParent(mozIApplica
     }
 
     std::vector<std::string> extraArgs;
     if (aIsNuwaProcess) {
         extraArgs.push_back("-nuwa");
     }
     mSubprocess->LaunchAndWaitForProcessHandle(extraArgs);
 
-    Open(mSubprocess->GetChannel(), mSubprocess->GetOwnedChildProcessHandle());
+    Open(mSubprocess->GetChannel(),
+         base::GetProcId(mSubprocess->GetChildProcessHandle()));
 
     InitInternal(aInitialPriority,
                  true, /* Setup off-main thread compositing */
                  true  /* Send registered chrome */);
 
     ContentProcessManager::GetSingleton()->AddContentProcess(this);
 
     ProcessHangMonitor::AddProcess(this);
@@ -2223,17 +2216,17 @@ ContentParent::ContentParent(ContentPare
     // Clone actors routed by aTemplate for this instance.
     IToplevelProtocol::SetTransport(mSubprocess->GetChannel());
     ProtocolCloneContext cloneContext;
     cloneContext.SetContentParent(this);
     CloneManagees(aTemplate, &cloneContext);
     CloneOpenedToplevels(aTemplate, aFds, aPid, &cloneContext);
 
     Open(mSubprocess->GetChannel(),
-         mSubprocess->GetChildProcessHandle());
+         base::GetProcId(mSubprocess->GetChildProcessHandle()));
 
     // Set the subprocess's priority (bg if we're a preallocated process, fg
     // otherwise).  We do this first because we're likely /lowering/ its CPU and
     // memory priority, which it has inherited from this process.
     ProcessPriority priority;
     if (IsPreallocated()) {
         priority = PROCESS_PRIORITY_PREALLOC;
     } else {
@@ -2251,19 +2244,16 @@ ContentParent::ContentParent(ContentPare
 #endif  // MOZ_NUWA_PROCESS
 
 ContentParent::~ContentParent()
 {
     if (mForceKillTimer) {
         mForceKillTimer->Cancel();
     }
 
-    if (OtherProcess())
-        base::CloseProcessHandle(OtherProcess());
-
     NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
     // We should be removed from all these lists in ActorDestroy.
     MOZ_ASSERT(!sPrivateContent || !sPrivateContent->Contains(this));
     if (mAppManifestURL.IsEmpty()) {
         MOZ_ASSERT(!sNonAppContentParents ||
                    !sNonAppContentParents->Contains(this));
     } else {
@@ -3298,29 +3288,36 @@ ContentParent::KillHard(const char* aRea
             }
             nsDependentCString reason(aReason);
             crashReporter->AnnotateCrashReport(
                 NS_LITERAL_CSTRING("ipc_channel_error"),
                 reason);
         }
     }
 #endif
-    if (!KillProcess(OtherProcess(), 1, false)) {
+    ProcessHandle otherProcessHandle;
+    if (!base::OpenProcessHandle(OtherPid(), &otherProcessHandle)) {
+        NS_ERROR("Failed to open child process when attempting kill.");
+        return;
+    }
+
+    if (!KillProcess(otherProcessHandle, base::PROCESS_END_KILLED_BY_USER,
+                     false)) {
         NS_WARNING("failed to kill subprocess!");
     }
+
     if (mSubprocess) {
         mSubprocess->SetAlreadyDead();
     }
+
+    // EnsureProcessTerminated has responsibilty for closing otherProcessHandle.
     XRE_GetIOMessageLoop()->PostTask(
         FROM_HERE,
         NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated,
-                            OtherProcess(), /*force=*/true));
-    // We've now closed the OtherProcess() handle, so must set it to null to
-    // prevent our dtor closing it twice.
-    SetOtherProcess(0);
+                            otherProcessHandle, /*force=*/true));
 }
 
 bool
 ContentParent::IsPreallocated()
 {
     return mAppManifestURL == MAGIC_PREALLOCATED_APP_MANIFEST_URL;
 }
 
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -18,17 +18,17 @@ ContentProcess::SetAppDir(const nsACStri
 {
   mXREEmbed.SetAppDir(aPath);
 }
 
 bool
 ContentProcess::Init()
 {
     mContent.Init(IOThreadChild::message_loop(),
-                         ParentHandle(),
+                         ParentPid(),
                          IOThreadChild::channel());
     mXREEmbed.Start();
     mContent.InitXPCOM();
     
     return true;
 }
 
 void
--- a/dom/ipc/ContentProcess.h
+++ b/dom/ipc/ContentProcess.h
@@ -18,18 +18,18 @@ namespace dom {
  * ContentProcess is a singleton on the content process which represents
  * the main thread where tab instances live.
  */
 class ContentProcess : public mozilla::ipc::ProcessChild
 {
     typedef mozilla::ipc::ProcessChild ProcessChild;
 
 public:
-    explicit ContentProcess(ProcessHandle mParentHandle)
-        : ProcessChild(mParentHandle)
+    explicit ContentProcess(ProcessId aParentPid)
+        : ProcessChild(aParentPid)
     { }
 
     ~ContentProcess()
     { }
 
     virtual bool Init() override;
     virtual void CleanUp() override;
 
--- a/dom/ipc/CrashReporterParent.h
+++ b/dom/ipc/CrashReporterParent.h
@@ -106,21 +106,24 @@ public:
   bool mInitialized;
 };
 
 #ifdef MOZ_CRASHREPORTER
 template<class Toplevel>
 inline bool
 CrashReporterParent::GeneratePairedMinidump(Toplevel* t)
 {
-  CrashReporter::ProcessHandle child;
+  mozilla::ipc::ScopedProcessHandle child;
 #ifdef XP_MACOSX
   child = t->Process()->GetChildTask();
 #else
-  child = t->OtherProcess();
+  if (!base::OpenPrivilegedProcessHandle(t->OtherPid(), &child.rwget())) {
+    NS_WARNING("Failed to open child process handle.");
+    return false;
+  }
 #endif
   nsCOMPtr<nsIFile> childDump;
   if (CrashReporter::CreatePairedMinidumps(child,
                                            mMainThread,
                                            getter_AddRefs(childDump)) &&
       CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) {
     return true;
   }
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -64,17 +64,17 @@ namespace {
 
 class HangMonitorChild
   : public PProcessHangMonitorChild
 {
  public:
   explicit HangMonitorChild(ProcessHangMonitor* aMonitor);
   virtual ~HangMonitorChild();
 
-  void Open(Transport* aTransport, ProcessHandle aHandle,
+  void Open(Transport* aTransport, ProcessId aOtherPid,
             MessageLoop* aIOLoop);
 
   typedef ProcessHangMonitor::SlowScriptAction SlowScriptAction;
   SlowScriptAction NotifySlowScript(nsITabChild* aTabChild,
                                     const char* aFileName,
                                     unsigned aLineNo);
   void NotifySlowScriptAsync(TabId aTabId,
                              const nsCString& aFileName,
@@ -166,18 +166,17 @@ private:
 
 class HangMonitorParent
   : public PProcessHangMonitorParent
 {
 public:
   explicit HangMonitorParent(ProcessHangMonitor* aMonitor);
   virtual ~HangMonitorParent();
 
-  void Open(Transport* aTransport, ProcessHandle aHandle,
-            MessageLoop* aIOLoop);
+  void Open(Transport* aTransport, ProcessId aPid, MessageLoop* aIOLoop);
 
   virtual bool RecvHangEvidence(const HangData& aHangData) override;
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   void SetProcess(HangMonitoredProcess* aProcess) { mProcess = aProcess; }
 
   void Shutdown();
@@ -307,25 +306,25 @@ HangMonitorChild::RecvEndStartingDebugge
   MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
 
   MonitorAutoLock lock(mMonitor);
   mFinishedStartingDebugger = true;
   return true;
 }
 
 void
-HangMonitorChild::Open(Transport* aTransport, ProcessHandle aHandle,
+HangMonitorChild::Open(Transport* aTransport, ProcessId aPid,
                        MessageLoop* aIOLoop)
 {
   MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
 
   MOZ_ASSERT(!sInstance);
   sInstance = this;
 
-  DebugOnly<bool> ok = PProcessHangMonitorChild::Open(aTransport, aHandle, aIOLoop);
+  DebugOnly<bool> ok = PProcessHangMonitorChild::Open(aTransport, aPid, aIOLoop);
   MOZ_ASSERT(ok);
 }
 
 void
 HangMonitorChild::NotifySlowScriptAsync(TabId aTabId,
                                         const nsCString& aFileName,
                                         unsigned aLineNo)
 {
@@ -484,22 +483,22 @@ HangMonitorParent::ShutdownOnThread()
 void
 HangMonitorParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
   mIPCOpen = false;
 }
 
 void
-HangMonitorParent::Open(Transport* aTransport, ProcessHandle aHandle,
+HangMonitorParent::Open(Transport* aTransport, ProcessId aPid,
                         MessageLoop* aIOLoop)
 {
   MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
 
-  DebugOnly<bool> ok = PProcessHangMonitorParent::Open(aTransport, aHandle, aIOLoop);
+  DebugOnly<bool> ok = PProcessHangMonitorParent::Open(aTransport, aPid, aIOLoop);
   MOZ_ASSERT(ok);
 }
 
 class HangObserverNotifier final : public nsRunnable
 {
 public:
   HangObserverNotifier(HangMonitoredProcess* aProcess, const HangData& aHangData)
     : mProcess(aProcess),
@@ -878,59 +877,47 @@ ProcessHangMonitor::NotifyPluginHang(uin
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   return HangMonitorChild::Get()->NotifyPluginHang(aPluginId);
 }
 
 PProcessHangMonitorParent*
 mozilla::CreateHangMonitorParent(ContentParent* aContentParent,
                                  mozilla::ipc::Transport* aTransport,
-                                 base::ProcessId aOtherProcess)
+                                 base::ProcessId aOtherPid)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
   HangMonitorParent* parent = new HangMonitorParent(monitor);
 
   HangMonitoredProcess* process = new HangMonitoredProcess(parent, aContentParent);
   parent->SetProcess(process);
 
-  base::ProcessHandle handle;
-  if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-    // XXX need to kill |aOtherProcess|, it's boned
-    return nullptr;
-  }
-
   monitor->MonitorLoop()->PostTask(
     FROM_HERE,
     NewRunnableMethod(parent, &HangMonitorParent::Open,
-                      aTransport, handle, XRE_GetIOMessageLoop()));
+                      aTransport, aOtherPid, XRE_GetIOMessageLoop()));
 
   return parent;
 }
 
 PProcessHangMonitorChild*
 mozilla::CreateHangMonitorChild(mozilla::ipc::Transport* aTransport,
-                                base::ProcessId aOtherProcess)
+                                base::ProcessId aOtherPid)
 {
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
 
   ProcessHangMonitor* monitor = ProcessHangMonitor::GetOrCreate();
   HangMonitorChild* child = new HangMonitorChild(monitor);
 
-  base::ProcessHandle handle;
-  if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-    // XXX need to kill |aOtherProcess|, it's boned
-    return nullptr;
-  }
-
   monitor->MonitorLoop()->PostTask(
     FROM_HERE,
     NewRunnableMethod(child, &HangMonitorChild::Open,
-                      aTransport, handle, XRE_GetIOMessageLoop()));
+                      aTransport, aOtherPid, XRE_GetIOMessageLoop()));
 
   return child;
 }
 
 MessageLoop*
 ProcessHangMonitor::MonitorLoop()
 {
   return mThread->message_loop();
--- a/dom/media/gmp/GMPChild.cpp
+++ b/dom/media/gmp/GMPChild.cpp
@@ -260,23 +260,23 @@ void
 GMPChild::CheckThread()
 {
   MOZ_ASSERT(mGMPMessageLoop == MessageLoop::current());
 }
 
 bool
 GMPChild::Init(const std::string& aPluginPath,
                const std::string& aVoucherPath,
-               base::ProcessHandle aParentProcessHandle,
+               base::ProcessId aParentPid,
                MessageLoop* aIOLoop,
                IPC::Channel* aChannel)
 {
   LOGD("%s pluginPath=%s", __FUNCTION__, aPluginPath.c_str());
 
-  if (NS_WARN_IF(!Open(aChannel, aParentProcessHandle, aIOLoop))) {
+  if (NS_WARN_IF(!Open(aChannel, aParentPid, aIOLoop))) {
     return false;
   }
 
 #ifdef MOZ_CRASHREPORTER
   SendPCrashReporterConstructor(CrashReporter::CurrentThreadId());
 #endif
 
   mPluginPath = aPluginPath;
--- a/dom/media/gmp/GMPChild.h
+++ b/dom/media/gmp/GMPChild.h
@@ -23,17 +23,17 @@ class GMPChild : public PGMPChild
                , public GMPAsyncShutdownHost
 {
 public:
   GMPChild();
   virtual ~GMPChild();
 
   bool Init(const std::string& aPluginPath,
             const std::string& aVoucherPath,
-            base::ProcessHandle aParentProcessHandle,
+            base::ProcessId aParentPid,
             MessageLoop* aIOLoop,
             IPC::Channel* aChannel);
 #ifdef XP_WIN
   bool PreLoadLibraries(const std::string& aPluginPath);
 #endif
   MessageLoop* GMPMessageLoop();
 
   // Main thread only.
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -144,17 +144,18 @@ GMPParent::LoadProcess()
       mProcess = nullptr;
       return NS_ERROR_FAILURE;
     }
 
 #ifdef PR_LOGGING
     mChildPid = base::GetProcId(mProcess->GetChildProcessHandle());
 #endif
 
-    bool opened = Open(mProcess->GetChannel(), mProcess->GetChildProcessHandle());
+    bool opened = Open(mProcess->GetChannel(),
+                       base::GetProcId(mProcess->GetChildProcessHandle()));
     if (!opened) {
       LOGD("%s: Failed to create new child process", __FUNCTION__);
       mProcess->Delete();
       mProcess = nullptr;
       return NS_ERROR_FAILURE;
     }
     LOGD("%s: Created new child process", __FUNCTION__);
 
--- a/dom/media/gmp/GMPProcessChild.cpp
+++ b/dom/media/gmp/GMPProcessChild.cpp
@@ -11,18 +11,18 @@
 #include "mozilla/ipc/IOThreadChild.h"
 #include "mozilla/BackgroundHangMonitor.h"
 
 using mozilla::ipc::IOThreadChild;
 
 namespace mozilla {
 namespace gmp {
 
-GMPProcessChild::GMPProcessChild(ProcessHandle parentHandle)
-: ProcessChild(parentHandle)
+GMPProcessChild::GMPProcessChild(ProcessId aParentPid)
+: ProcessChild(aParentPid)
 {
 }
 
 GMPProcessChild::~GMPProcessChild()
 {
 }
 
 bool
@@ -47,17 +47,17 @@ GMPProcessChild::Init()
 #else
 #error Not implemented
 #endif
 
   BackgroundHangMonitor::Startup();
 
   return mPlugin.Init(pluginFilename,
                       voucherFilename,
-                      ParentHandle(),
+                      ParentPid(),
                       IOThreadChild::message_loop(),
                       IOThreadChild::channel());
 }
 
 void
 GMPProcessChild::CleanUp()
 {
   BackgroundHangMonitor::Shutdown();
--- a/dom/media/gmp/GMPProcessChild.h
+++ b/dom/media/gmp/GMPProcessChild.h
@@ -14,17 +14,17 @@ namespace gmp {
 
 class GMPLoader;
 
 class GMPProcessChild final : public mozilla::ipc::ProcessChild {
 protected:
   typedef mozilla::ipc::ProcessChild ProcessChild;
 
 public:
-  explicit GMPProcessChild(ProcessHandle parentHandle);
+  explicit GMPProcessChild(ProcessId aParentPid);
   ~GMPProcessChild();
 
   virtual bool Init() override;
   virtual void CleanUp() override;
 
   // Set/get the GMPLoader singleton for this child process.
   // Note: The GMPLoader is not deleted by this object, the caller of
   // SetGMPLoader() must manage the GMPLoader's lifecycle.
--- a/dom/plugins/ipc/PluginInstanceChild.cpp
+++ b/dom/plugins/ipc/PluginInstanceChild.cpp
@@ -3388,17 +3388,17 @@ PluginInstanceChild::ShowPluginFrame()
         XSync(mWsInfo.display, False);
     } else
 #endif
 #ifdef XP_WIN
     if (SharedDIBSurface::IsSharedDIBSurface(mCurrentSurface)) {
         SharedDIBSurface* s = static_cast<SharedDIBSurface*>(mCurrentSurface.get());
         if (!mCurrentSurfaceActor) {
             base::SharedMemoryHandle handle = nullptr;
-            s->ShareToProcess(OtherProcess(), &handle);
+            s->ShareToProcess(OtherPid(), &handle);
 
             mCurrentSurfaceActor =
                 SendPPluginSurfaceConstructor(handle,
                                               mCurrentSurface->GetSize(),
                                               haveTransparentPixels);
         }
         currSurf = mCurrentSurfaceActor;
         s->Flush();
--- a/dom/plugins/ipc/PluginInstanceParent.cpp
+++ b/dom/plugins/ipc/PluginInstanceParent.cpp
@@ -1935,18 +1935,19 @@ PluginInstanceParent::SharedSurfaceSetWi
     if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
                                            newPort.width, newPort.height, false)))
       return false;
 
     // save the new shared surface size we just allocated
     mSharedSize = newPort;
 
     base::SharedMemoryHandle handle;
-    if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(OtherProcess(), &handle)))
+    if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(OtherPid(), &handle))) {
       return false;
+    }
 
     aRemoteWindow.surfaceHandle = handle;
 
     return true;
 }
 
 void
 PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -105,26 +105,21 @@ struct RunnableMethodTraits<PluginModule
 {
     static void RetainCallee(PluginModuleChild* obj) { }
     static void ReleaseCallee(PluginModuleChild* obj) { }
 };
 
 /* static */
 PluginModuleChild*
 PluginModuleChild::CreateForContentProcess(mozilla::ipc::Transport* aTransport,
-                                           base::ProcessId aOtherProcess)
+                                           base::ProcessId aOtherPid)
 {
     PluginModuleChild* child = new PluginModuleChild(false);
-    ProcessHandle handle;
-    if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-        // XXX need to kill |aOtherProcess|, it's boned
-        return nullptr;
-    }
-
-    if (!child->InitForContent(handle, XRE_GetIOMessageLoop(), aTransport)) {
+
+    if (!child->InitForContent(aOtherPid, XRE_GetIOMessageLoop(), aTransport)) {
         return nullptr;
     }
 
     return child;
 }
 
 PluginModuleChild::PluginModuleChild(bool aIsChrome)
   : mLibrary(0)
@@ -201,44 +196,45 @@ PluginModuleChild::GetChrome()
     // A special PluginModuleChild instance that talks to the chrome process
     // during startup and shutdown. Synchronous messages to or from this actor
     // should be avoided because they may lead to hangs.
     MOZ_ASSERT(gChromeInstance);
     return gChromeInstance;
 }
 
 bool
-PluginModuleChild::CommonInit(base::ProcessHandle aParentProcessHandle,
+PluginModuleChild::CommonInit(base::ProcessId aParentPid,
                               MessageLoop* aIOLoop,
                               IPC::Channel* aChannel)
 {
     PLUGIN_LOG_DEBUG_METHOD;
 
     // Request Windows message deferral behavior on our channel. This
     // applies to the top level and all sub plugin protocols since they
     // all share the same channel.
     // Bug 1090573 - Don't do this for connections to content processes.
     GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
 
-    if (!Open(aChannel, aParentProcessHandle, aIOLoop))
+    if (!Open(aChannel, aParentPid, aIOLoop)) {
         return false;
+    }
 
     memset((void*) &mFunctions, 0, sizeof(mFunctions));
     mFunctions.size = sizeof(mFunctions);
     mFunctions.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
 
     return true;
 }
 
 bool
-PluginModuleChild::InitForContent(base::ProcessHandle aParentProcessHandle,
+PluginModuleChild::InitForContent(base::ProcessId aParentPid,
                                   MessageLoop* aIOLoop,
                                   IPC::Channel* aChannel)
 {
-    if (!CommonInit(aParentProcessHandle, aIOLoop, aChannel)) {
+    if (!CommonInit(aParentPid, aIOLoop, aChannel)) {
         return false;
     }
 
     mTransport = aChannel;
 
     mLibrary = GetChrome()->mLibrary;
     mFunctions = GetChrome()->mFunctions;
 
@@ -254,17 +250,17 @@ PluginModuleChild::RecvDisableFlashProte
 #else
     MOZ_ASSERT(false, "Should not be called");
 #endif
     return true;
 }
 
 bool
 PluginModuleChild::InitForChrome(const std::string& aPluginFilename,
-                                 base::ProcessHandle aParentProcessHandle,
+                                 base::ProcessId aParentPid,
                                  MessageLoop* aIOLoop,
                                  IPC::Channel* aChannel)
 {
     NS_ASSERTION(aChannel, "need a channel");
 
     if (!InitGraphics())
         return false;
 
@@ -307,17 +303,17 @@ PluginModuleChild::InitForChrome(const s
 #endif
     {
         nsresult rv = pluginFile.LoadPlugin(&mLibrary);
         if (NS_FAILED(rv))
             return false;
     }
     NS_ASSERTION(mLibrary, "couldn't open shared object");
 
-    if (!CommonInit(aParentProcessHandle, aIOLoop, aChannel)) {
+    if (!CommonInit(aParentPid, aIOLoop, aChannel)) {
         return false;
     }
 
     GetIPCChannel()->SetAbortOnError(true);
 
     // TODO: use PluginPRLibrary here
 
 #if defined(OS_LINUX) || defined(OS_BSD)
@@ -786,19 +782,19 @@ void
 PluginModuleChild::QuickExit()
 {
     NS_WARNING("plugin process _exit()ing");
     _exit(0);
 }
 
 PPluginModuleChild*
 PluginModuleChild::AllocPPluginModuleChild(mozilla::ipc::Transport* aTransport,
-                                           base::ProcessId aOtherProcess)
+                                           base::ProcessId aOtherPid)
 {
-    return PluginModuleChild::CreateForContentProcess(aTransport, aOtherProcess);
+    return PluginModuleChild::CreateForContentProcess(aTransport, aOtherPid);
 }
 
 PCrashReporterChild*
 PluginModuleChild::AllocPCrashReporterChild(mozilla::dom::NativeThreadId* id,
                                             uint32_t* processType)
 {
     return new CrashReporterChild();
 }
--- a/dom/plugins/ipc/PluginModuleChild.h
+++ b/dom/plugins/ipc/PluginModuleChild.h
@@ -153,27 +153,27 @@ protected:
                                    nsTArray<nsCString>&& aThreadNameFilters) override;
     virtual bool RecvStopProfiler() override;
     virtual bool AnswerGetProfile(nsCString* aProfile) override;
 
 public:
     explicit PluginModuleChild(bool aIsChrome);
     virtual ~PluginModuleChild();
 
-    bool CommonInit(base::ProcessHandle aParentProcessHandle,
+    bool CommonInit(base::ProcessId aParentPid,
                     MessageLoop* aIOLoop,
                     IPC::Channel* aChannel);
 
     // aPluginFilename is UTF8, not native-charset!
     bool InitForChrome(const std::string& aPluginFilename,
-                       base::ProcessHandle aParentProcessHandle,
+                       base::ProcessId aParentPid,
                        MessageLoop* aIOLoop,
                        IPC::Channel* aChannel);
 
-    bool InitForContent(base::ProcessHandle aParentProcessHandle,
+    bool InitForContent(base::ProcessId aParentPid,
                         MessageLoop* aIOLoop,
                         IPC::Channel* aChannel);
 
     static PluginModuleChild*
     CreateForContentProcess(mozilla::ipc::Transport* aTransport,
                             base::ProcessId aOtherProcess);
 
     void CleanUp();
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -382,40 +382,35 @@ PluginModuleContentParent::LoadModule(ui
 
     parent->mPluginId = aPluginId;
 
     return parent;
 }
 
 /* static */ void
 PluginModuleContentParent::AssociatePluginId(uint32_t aPluginId,
-                                             base::ProcessId aProcessId)
+                                             base::ProcessId aOtherPid)
 {
     DebugOnly<PluginModuleMapping*> mapping =
-        PluginModuleMapping::AssociateWithProcessId(aPluginId, aProcessId);
+        PluginModuleMapping::AssociateWithProcessId(aPluginId, aOtherPid);
     MOZ_ASSERT(mapping);
 }
 
 /* static */ PluginModuleContentParent*
 PluginModuleContentParent::Initialize(mozilla::ipc::Transport* aTransport,
-                                      base::ProcessId aOtherProcess)
+                                      base::ProcessId aOtherPid)
 {
     nsAutoPtr<PluginModuleMapping> moduleMapping(
-        PluginModuleMapping::Resolve(aOtherProcess));
+        PluginModuleMapping::Resolve(aOtherPid));
     MOZ_ASSERT(moduleMapping);
     PluginModuleContentParent* parent = moduleMapping->GetModule();
     MOZ_ASSERT(parent);
 
-    ProcessHandle handle;
-    if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-        // Bug 1090578 - need to kill |aOtherProcess|, it's boned.
-        return nullptr;
-    }
-
-    DebugOnly<bool> ok = parent->Open(aTransport, handle, XRE_GetIOMessageLoop(),
+    DebugOnly<bool> ok = parent->Open(aTransport, aOtherPid,
+                                      XRE_GetIOMessageLoop(),
                                       mozilla::ipc::ParentSide);
     MOZ_ASSERT(ok);
 
     moduleMapping->SetChannelOpened();
 
     // Request Windows message deferral behavior on our channel. This
     // applies to the top level and all sub plugin protocols since they
     // all share the same channel.
@@ -449,17 +444,17 @@ PluginModuleChromeParent::SetContentPare
     MOZ_ASSERT(aContentParent);
     mContentParent = aContentParent;
 }
 
 bool
 PluginModuleChromeParent::SendAssociatePluginId()
 {
     MOZ_ASSERT(mContentParent);
-    return mContentParent->SendAssociatePluginId(mPluginId, OtherSidePID());
+    return mContentParent->SendAssociatePluginId(mPluginId, OtherPid());
 }
 
 // static
 PluginLibrary*
 PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
                                      nsPluginTag* aPluginTag)
 {
     PLUGIN_LOG_DEBUG_FUNCTION;
@@ -508,17 +503,19 @@ PluginModuleChromeParent::OnProcessLaunc
         OnInitFailure();
         return;
     }
     // We may have already been initialized by another call that was waiting
     // for process connect. If so, this function doesn't need to run.
     if (mAsyncInitRv != NS_ERROR_NOT_INITIALIZED || mShutdown) {
         return;
     }
-    Open(mSubprocess->GetChannel(), mSubprocess->GetChildProcessHandle());
+
+    Open(mSubprocess->GetChannel(),
+         base::GetProcId(mSubprocess->GetChildProcessHandle()));
 
     // Request Windows message deferral behavior on our channel. This
     // applies to the top level and all sub plugin protocols since they
     // all share the same channel.
     GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
 
     TimeoutChanged(CHILD_TIMEOUT_PREF, this);
 
@@ -1216,50 +1213,58 @@ PluginModuleChromeParent::TerminateChild
         crashReporter->AnnotateCrashReport(
             NS_LITERAL_CSTRING("additional_minidumps"),
             additionalDumps);
     } else {
         NS_WARNING("failed to capture paired minidumps from hang");
     }
 #endif
 
+    mozilla::ipc::ScopedProcessHandle geckoChildProcess;
+    bool childOpened = base::OpenProcessHandle(OtherPid(),
+                                               &geckoChildProcess.rwget());
+
 #ifdef XP_WIN
     // collect cpu usage for plugin processes
 
     InfallibleTArray<base::ProcessHandle> processHandles;
 
-    processHandles.AppendElement(OtherProcess());
+    if (childOpened) {
+        processHandles.AppendElement(geckoChildProcess);
+    }
 
 #ifdef MOZ_CRASHREPORTER_INJECTOR
-    {
-      base::ProcessHandle handle;
-      if (mFlashProcess1 && base::OpenProcessHandle(mFlashProcess1, &handle)) {
-        processHandles.AppendElement(handle);
-      }
-      if (mFlashProcess2 && base::OpenProcessHandle(mFlashProcess2, &handle)) {
-        processHandles.AppendElement(handle);
-      }
+    mozilla::ipc::ScopedProcessHandle flashBrokerProcess;
+    if (mFlashProcess1 &&
+        base::OpenProcessHandle(mFlashProcess1, &flashBrokerProcess.rwget())) {
+        processHandles.AppendElement(flashBrokerProcess);
+    }
+    mozilla::ipc::ScopedProcessHandle flashSandboxProcess;
+    if (mFlashProcess2 &&
+        base::OpenProcessHandle(mFlashProcess2, &flashSandboxProcess.rwget())) {
+        processHandles.AppendElement(flashSandboxProcess);
     }
 #endif
 
     if (!GetProcessCpuUsage(processHandles, mPluginCpuUsageOnHang)) {
       mPluginCpuUsageOnHang.Clear();
     }
 #endif
 
     // this must run before the error notification from the channel,
     // or not at all
     bool isFromHangUI = aMsgLoop != MessageLoop::current();
     aMsgLoop->PostTask(
         FROM_HERE,
         mChromeTaskFactory.NewRunnableMethod(
             &PluginModuleChromeParent::CleanupFromTimeout, isFromHangUI));
 
-    if (!KillProcess(OtherProcess(), 1, false))
+    if (!childOpened || !KillProcess(geckoChildProcess, 1, false)) {
         NS_WARNING("failed to kill subprocess!");
+    }
 }
 
 bool
 PluginModuleParent::GetPluginDetails()
 {
     nsRefPtr<nsPluginHost> host = nsPluginHost::GetInst();
     if (!host) {
         return false;
@@ -2667,17 +2672,17 @@ PluginModuleParent::RecvPluginShowWindow
 #endif
 }
 
 bool
 PluginModuleParent::RecvPluginHideWindow(const uint32_t& aWindowId)
 {
     PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
 #if defined(XP_MACOSX)
-    mac_plugin_interposing::parent::OnPluginHideWindow(aWindowId, OtherSidePID());
+    mac_plugin_interposing::parent::OnPluginHideWindow(aWindowId, OtherPid());
     return true;
 #else
     NS_NOTREACHED(
         "PluginInstanceParent::RecvPluginHideWindow not implemented!");
     return false;
 #endif
 }
 
@@ -2888,17 +2893,25 @@ PluginModuleChromeParent::GetToolhelpSna
     return 0;
 }
 
 void
 PluginModuleChromeParent::OnCrash(DWORD processID)
 {
     if (!mShutdown) {
         GetIPCChannel()->CloseWithError();
-        KillProcess(OtherProcess(), 1, false);
+        mozilla::ipc::ScopedProcessHandle geckoPluginChild;
+        if (base::OpenProcessHandle(OtherPid(), &geckoPluginChild.rwget())) {
+            if (!base::KillProcess(geckoPluginChild,
+                                   base::PROCESS_END_KILLED_BY_USER, false)) {
+                NS_ERROR("May have failed to kill child process.");
+            }
+        } else {
+            NS_ERROR("Failed to open child process when attempting kill.");
+        }
     }
 }
 
 #endif // MOZ_CRASHREPORTER_INJECTOR
 
 #ifdef MOZ_ENABLE_PROFILER_SPS
 class PluginProfilerObserver final : public nsIObserver,
                                      public nsSupportsWeakReference
--- a/dom/plugins/ipc/PluginProcessChild.cpp
+++ b/dom/plugins/ipc/PluginProcessChild.cpp
@@ -135,17 +135,17 @@ PluginProcessChild::Init()
 #  error Sorry
 #endif
 
     if (NS_FAILED(nsRegion::InitStatic())) {
       NS_ERROR("Could not initialize nsRegion");
       return false;
     }
 
-    bool retval = mPlugin.InitForChrome(pluginFilename, ParentHandle(),
+    bool retval = mPlugin.InitForChrome(pluginFilename, ParentPid(),
                                         IOThreadChild::message_loop(),
                                         IOThreadChild::channel());
 #if defined(XP_MACOSX)
     if (nsCocoaFeatures::OnYosemiteOrLater()) {
       // Explicitly turn off CGEvent logging.  This works around bug 1092855.
       // If there are already CGEvents in the log, turning off logging also
       // causes those events to be written to disk.  But at this point no
       // CGEvents have yet been processed.  CGEvents are events (usually
--- a/dom/plugins/ipc/PluginProcessChild.h
+++ b/dom/plugins/ipc/PluginProcessChild.h
@@ -14,18 +14,18 @@ namespace mozilla {
 namespace plugins {
 //-----------------------------------------------------------------------------
 
 class PluginProcessChild : public mozilla::ipc::ProcessChild {
 protected:
     typedef mozilla::ipc::ProcessChild ProcessChild;
 
 public:
-    explicit PluginProcessChild(ProcessHandle aParentHandle)
-      : ProcessChild(aParentHandle), mPlugin(true)
+    explicit PluginProcessChild(ProcessId aParentPid)
+      : ProcessChild(aParentPid), mPlugin(true)
     { }
 
     virtual ~PluginProcessChild()
     { }
 
     virtual bool Init() override;
     virtual void CleanUp() override;
 
--- a/gfx/ipc/SharedDIB.cpp
+++ b/gfx/ipc/SharedDIB.cpp
@@ -57,21 +57,21 @@ SharedDIB::Attach(Handle aHandle, uint32
   mShMem = new base::SharedMemory(aHandle, false);
   if(!mShMem)
     return NS_ERROR_OUT_OF_MEMORY;
 
   return NS_OK;
 }
 
 nsresult
-SharedDIB::ShareToProcess(base::ProcessHandle aChildProcess, Handle *aChildHandle)
+SharedDIB::ShareToProcess(base::ProcessId aTargetPid, Handle *aNewHandle)
 {
   if (!mShMem)
     return NS_ERROR_UNEXPECTED;
 
-  if (!mShMem->ShareToProcess(aChildProcess, aChildHandle))
+  if (!mShMem->ShareToProcess(aTargetPid, aNewHandle))
     return NS_ERROR_UNEXPECTED;
 
   return NS_OK;
 }
 
 } // gfx
 } // mozilla
--- a/gfx/ipc/SharedDIB.h
+++ b/gfx/ipc/SharedDIB.h
@@ -31,17 +31,17 @@ public:
   bool IsValid();
 
   // Wrap a new shared dib around allocated shared memory. Note aHandle must point
   // to a memory section large enough to hold a dib of size aSize, otherwise this
   // will fail.
   nsresult Attach(Handle aHandle, uint32_t aSize);
 
   // Returns a SharedMemoryHandle suitable for sharing with another process.
-  nsresult ShareToProcess(base::ProcessHandle aChildProcess, Handle *aChildHandle);
+  nsresult ShareToProcess(base::ProcessId aTargetPid, Handle *aNewHandle);
 
 protected:
   base::SharedMemory *mShMem;
 };
 
 } // gfx
 } // mozilla
 
--- a/gfx/ipc/SharedDIBSurface.h
+++ b/gfx/ipc/SharedDIBSurface.h
@@ -39,18 +39,18 @@ public:
   /**
    * After drawing to a surface via GDI, GDI must be flushed before the bitmap
    * is valid.
    */
   void Flush() { ::GdiFlush(); }
 
   HDC GetHDC() { return mSharedDIB.GetHDC(); }
 
-  nsresult ShareToProcess(base::ProcessHandle aChildProcess, Handle* aChildHandle) {
-    return mSharedDIB.ShareToProcess(aChildProcess, aChildHandle);
+  nsresult ShareToProcess(base::ProcessId aTargetPid, Handle* aNewHandle) {
+    return mSharedDIB.ShareToProcess(aTargetPid, aNewHandle);
   }
 
   static bool IsSharedDIBSurface(gfxASurface* aSurface);
 
 private:
   SharedDIBWin mSharedDIB;
 
   void InitSurface(uint32_t aWidth, uint32_t aHeight, bool aTransparent);
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3221,25 +3221,25 @@ void AsyncPanZoomController::ShareCompos
     if (frame) {
 
       { // scope the monitor, only needed to copy the FrameMetrics.
         ReentrantMonitorAutoEnter lock(mMonitor);
         *frame = mFrameMetrics;
       }
 
       // Get the process id of the content process
-      base::ProcessHandle processHandle = compositor->OtherProcess();
+      base::ProcessId otherPid = compositor->OtherPid();
       ipc::SharedMemoryBasic::Handle mem = ipc::SharedMemoryBasic::NULLHandle();
 
       // Get the shared memory handle to share with the content process
-      mSharedFrameMetricsBuffer->ShareToProcess(processHandle, &mem);
+      mSharedFrameMetricsBuffer->ShareToProcess(otherPid, &mem);
 
       // Get the cross process mutex handle to share with the content process
       mSharedLock = new CrossProcessMutex("AsyncPanZoomControlLock");
-      CrossProcessMutexHandle handle = mSharedLock->ShareToProcess(processHandle);
+      CrossProcessMutexHandle handle = mSharedLock->ShareToProcess(otherPid);
 
       // Send the shared memory handle and cross process handle to the content
       // process by an asynchronous ipc call. Include the APZC unique ID
       // so the content process know which APZC sent this shared FrameMetrics.
       if (!compositor->SendSharedCompositorFrameMetrics(mem, handle, mLayersId, mAPZCId)) {
         APZC_LOG("%p failed to share FrameMetrics with content process.", this);
       }
     }
--- a/gfx/layers/ipc/CompositorChild.cpp
+++ b/gfx/layers/ipc/CompositorChild.cpp
@@ -3,17 +3,16 @@
 /* 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/layers/CompositorChild.h"
 #include <stddef.h>                     // for size_t
 #include "ClientLayerManager.h"         // for ClientLayerManager
 #include "base/message_loop.h"          // for MessageLoop
-#include "base/process_util.h"          // for OpenProcessHandle
 #include "base/task.h"                  // for NewRunnableMethod, etc
 #include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/PLayerTransactionChild.h"
 #include "mozilla/mozalloc.h"           // for operator new, etc
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsIObserver.h"                // for nsIObserver
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
@@ -72,29 +71,23 @@ CompositorChild::LookupCompositorFrameMe
   if (data) {
     data->CopyFrameMetrics(&aFrame);
     return true;
   }
   return false;
 }
 
 /*static*/ PCompositorChild*
-CompositorChild::Create(Transport* aTransport, ProcessId aOtherProcess)
+CompositorChild::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   // There's only one compositor per child process.
   MOZ_ASSERT(!sCompositor);
 
   nsRefPtr<CompositorChild> child(new CompositorChild(nullptr));
-  ProcessHandle handle;
-  if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-    // We can't go on without a compositor.
-    NS_RUNTIMEABORT("Couldn't OpenProcessHandle() to parent process.");
-    return nullptr;
-  }
-  if (!child->Open(aTransport, handle, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
+  if (!child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
     NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
     return nullptr;
   }
 
   // We release this ref in ActorDestroy().
   sCompositor = child.forget().take();
 
   int32_t width;
--- a/gfx/layers/ipc/CompositorParent.cpp
+++ b/gfx/layers/ipc/CompositorParent.cpp
@@ -7,18 +7,17 @@
 #include "mozilla/layers/CompositorParent.h"
 #include <stdio.h>                      // for fprintf, stdout
 #include <stdint.h>                     // for uint64_t
 #include <map>                          // for _Rb_tree_iterator, etc
 #include <utility>                      // for pair
 #include "LayerTransactionParent.h"     // for LayerTransactionParent
 #include "RenderTrace.h"                // for RenderTraceLayers
 #include "base/message_loop.h"          // for MessageLoop
-#include "base/process.h"               // for ProcessHandle
-#include "base/process_util.h"          // for OpenProcessHandle
+#include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, etc
 #include "base/thread.h"                // for Thread
 #include "base/tracked.h"               // for FROM_HERE
 #include "gfxContext.h"                 // for gfxContext
 #include "gfxPlatform.h"                // for gfxPlatform
 #ifdef MOZ_WIDGET_GTK
 #include "gfxPlatformGtk.h"             // for gfxPlatform
 #endif
@@ -73,17 +72,17 @@
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::ipc;
 using namespace mozilla::gfx;
 using namespace std;
 
-using base::ProcessHandle;
+using base::ProcessId;
 using base::Thread;
 
 CompositorParent::LayerTreeState::LayerTreeState()
   : mParent(nullptr)
   , mLayerManager(nullptr)
   , mCrossProcessParent(nullptr)
   , mLayerTree(nullptr)
   , mUpdatedPluginDataAvailable(false)
@@ -1296,30 +1295,26 @@ CompositorParent::AllocPLayerTransaction
   nsIntRect rect;
   mWidget->GetClientBounds(rect);
   InitializeLayerManager(aBackendHints);
   mWidget = nullptr;
 
   if (!mLayerManager) {
     NS_WARNING("Failed to initialise Compositor");
     *aSuccess = false;
-    LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0,
-                                                           // child side's process id is current process Id
-                                                           base::GetProcId(base::GetCurrentProcessHandle()));
+    LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0);
     p->AddIPDLReference();
     return p;
   }
 
   mCompositionManager = new AsyncCompositionManager(mLayerManager);
   *aSuccess = true;
 
   *aTextureFactoryIdentifier = mCompositor->GetTextureFactoryIdentifier();
-  LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0,
-                                                         // child side's process id is current process Id
-                                                         base::GetProcId(base::GetCurrentProcessHandle()));
+  LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0);
   p->AddIPDLReference();
   return p;
 }
 
 bool
 CompositorParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor)
 {
   static_cast<LayerTransactionParent*>(actor)->ReleaseIPDLReference();
@@ -1515,19 +1510,18 @@ CompositorParent::RequestNotifyLayerTree
  */
 class CrossProcessCompositorParent final : public PCompositorParent,
                                            public ShadowLayersManager
 {
   friend class CompositorParent;
 
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(CrossProcessCompositorParent)
 public:
-  CrossProcessCompositorParent(Transport* aTransport, ProcessId aOtherProcess)
+  explicit CrossProcessCompositorParent(Transport* aTransport)
     : mTransport(aTransport)
-    , mChildProcessId(aOtherProcess)
     , mCompositorThreadHolder(sCompositorThreadHolder)
     , mNotifyAfterRemotePaint(false)
   {
     MOZ_ASSERT(NS_IsMainThread());
     gfxPlatform::GetPlatform()->ComputeTileSize();
   }
 
   // IToplevelProtocol::CloneToplevel()
@@ -1600,18 +1594,16 @@ private:
 
   void DeferredDestroy();
 
   // There can be many CPCPs, and IPDL-generated code doesn't hold a
   // reference to top-level actors.  So we hold a reference to
   // ourself.  This is released (deferred) in ActorDestroy().
   nsRefPtr<CrossProcessCompositorParent> mSelfRef;
   Transport* mTransport;
-  // Child side's process Id.
-  base::ProcessId mChildProcessId;
 
   nsRefPtr<CompositorThreadHolder> mCompositorThreadHolder;
   // If true, we should send a RemotePaintIsReady message when the layer transaction
   // is received
   bool mNotifyAfterRemotePaint;
 };
 
 void
@@ -1629,41 +1621,36 @@ CompositorParent::DidComposite()
     if (lts->mParent == this && lts->mCrossProcessParent) {
       static_cast<CrossProcessCompositorParent*>(lts->mCrossProcessParent)->DidComposite(it->first);
     }
   }
 }
 
 static void
 OpenCompositor(CrossProcessCompositorParent* aCompositor,
-               Transport* aTransport, ProcessHandle aHandle,
+               Transport* aTransport, ProcessId aOtherPid,
                MessageLoop* aIOLoop)
 {
-  DebugOnly<bool> ok = aCompositor->Open(aTransport, aHandle, aIOLoop);
+  DebugOnly<bool> ok = aCompositor->Open(aTransport, aOtherPid, aIOLoop);
   MOZ_ASSERT(ok);
 }
 
 /*static*/ PCompositorParent*
-CompositorParent::Create(Transport* aTransport, ProcessId aOtherProcess)
+CompositorParent::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   gfxPlatform::InitLayersIPC();
 
   nsRefPtr<CrossProcessCompositorParent> cpcp =
-    new CrossProcessCompositorParent(aTransport, aOtherProcess);
-  ProcessHandle handle;
-  if (!base::OpenProcessHandle(aOtherProcess, &handle)) {
-    // XXX need to kill |aOtherProcess|, it's boned
-    return nullptr;
-  }
+    new CrossProcessCompositorParent(aTransport);
 
   cpcp->mSelfRef = cpcp;
   CompositorLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(OpenCompositor, cpcp.get(),
-                        aTransport, handle, XRE_GetIOMessageLoop()));
+                        aTransport, aOtherPid, XRE_GetIOMessageLoop()));
   // The return value is just compared to null for success checking,
   // we're not sharing a ref.
   return cpcp.get();
 }
 
 IToplevelProtocol*
 CompositorParent::CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
                                 base::ProcessHandle aPeerProcess,
@@ -1732,27 +1719,27 @@ CrossProcessCompositorParent::AllocPLaye
     state = &itr->second;
   }
 
   if (state && state->mLayerManager) {
     state->mCrossProcessParent = this;
     LayerManagerComposite* lm = state->mLayerManager;
     *aTextureFactoryIdentifier = lm->GetCompositor()->GetTextureFactoryIdentifier();
     *aSuccess = true;
-    LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId, mChildProcessId);
+    LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId);
     p->AddIPDLReference();
     sIndirectLayerTrees[aId].mLayerTree = p;
     return p;
   }
 
   NS_WARNING("Created child without a matching parent?");
   // XXX: should be false, but that causes us to fail some tests on Mac w/ OMTC.
   // Bug 900745. change *aSuccess to false to see test failures.
   *aSuccess = true;
-  LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId, mChildProcessId);
+  LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId);
   p->AddIPDLReference();
   return p;
 }
 
 bool
 CrossProcessCompositorParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers)
 {
   LayerTransactionParent* slp = static_cast<LayerTransactionParent*>(aLayers);
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -6,18 +6,17 @@
 #include "ImageBridgeChild.h"
 #include <vector>                       // for vector
 #include "ImageBridgeParent.h"          // for ImageBridgeParent
 #include "ImageContainer.h"             // for ImageContainer
 #include "Layers.h"                     // for Layer, etc
 #include "ShadowLayers.h"               // for ShadowLayerForwarder
 #include "base/message_loop.h"          // for MessageLoop
 #include "base/platform_thread.h"       // for PlatformThread
-#include "base/process.h"               // for ProcessHandle
-#include "base/process_util.h"          // for OpenProcessHandle
+#include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for NewRunnableFunction, etc
 #include "base/thread.h"                // for Thread
 #include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/Monitor.h"            // for Monitor, MonitorAutoLock
 #include "mozilla/ReentrantMonitor.h"   // for ReentrantMonitor, etc
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/Transport.h"      // for Transport
@@ -44,17 +43,17 @@ struct nsIntRect;
 namespace mozilla {
 namespace ipc {
 class Shmem;
 }
 
 namespace layers {
 
 using base::Thread;
-using base::ProcessHandle;
+using base::ProcessId;
 using namespace mozilla::ipc;
 using namespace mozilla::gfx;
 
 typedef std::vector<CompositableOperation> OpVector;
 
 struct CompositableTransaction
 {
   CompositableTransaction()
@@ -317,20 +316,20 @@ void ImageBridgeChild::StartUp()
 }
 
 #ifdef MOZ_NUWA_PROCESS
 #include "ipc/Nuwa.h"
 #endif
 
 static void
 ConnectImageBridgeInChildProcess(Transport* aTransport,
-                                 ProcessHandle aOtherProcess)
+                                 ProcessId aOtherPid)
 {
   // Bind the IPC channel to the image bridge thread.
-  sImageBridgeChildSingleton->Open(aTransport, aOtherProcess,
+  sImageBridgeChildSingleton->Open(aTransport, aOtherPid,
                                    XRE_GetIOMessageLoop(),
                                    ipc::ChildSide);
 #ifdef MOZ_NUWA_PROCESS
   if (IsNuwaProcess()) {
     sImageBridgeChildThread
       ->message_loop()->PostTask(FROM_HERE,
                                  NewRunnableFunction(NuwaMarkCurrentThread,
                                                      (void (*)(void *))nullptr,
@@ -544,37 +543,32 @@ ImageBridgeChild::EndTransaction()
     }
   }
   SendPendingAsyncMessges();
 }
 
 
 PImageBridgeChild*
 ImageBridgeChild::StartUpInChildProcess(Transport* aTransport,
-                                        ProcessId aOtherProcess)
+                                        ProcessId aOtherPid)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   gfxPlatform::GetPlatform();
 
-  ProcessHandle processHandle;
-  if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
-    return nullptr;
-  }
-
   sImageBridgeChildThread = new Thread("ImageBridgeChild");
   if (!sImageBridgeChildThread->Start()) {
     return nullptr;
   }
 
   sImageBridgeChildSingleton = new ImageBridgeChild();
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(ConnectImageBridgeInChildProcess,
-                        aTransport, processHandle));
+                        aTransport, aOtherPid));
 
   return sImageBridgeChildSingleton;
 }
 
 void ImageBridgeChild::ShutDown()
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (ImageBridgeChild::IsCreated()) {
@@ -616,17 +610,17 @@ bool ImageBridgeChild::StartUpOnThread(T
   MOZ_ASSERT(aThread, "ImageBridge needs a thread.");
   if (sImageBridgeChildSingleton == nullptr) {
     sImageBridgeChildThread = aThread;
     if (!aThread->IsRunning()) {
       aThread->Start();
     }
     sImageBridgeChildSingleton = new ImageBridgeChild();
     sImageBridgeParentSingleton = new ImageBridgeParent(
-      CompositorParent::CompositorLoop(), nullptr, base::GetProcId(base::GetCurrentProcessHandle()));
+      CompositorParent::CompositorLoop(), nullptr, ipc::kCurrentProcessId);
     sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
     return true;
   } else {
     return false;
   }
 }
 
 bool InImageBridgeChildThread()
@@ -944,17 +938,17 @@ void ImageBridgeChild::RemoveTexture(Tex
   // the other thread
   while (!done) {
     barrier.Wait();
   }
 }
 
 bool ImageBridgeChild::IsSameProcess() const
 {
-  return OtherProcess() == ipc::kInvalidProcessHandle;
+  return OtherPid() == ipc::kCurrentProcessId;
 }
 
 void ImageBridgeChild::SendPendingAsyncMessges()
 {
   if (!IsCreated() ||
       mTransactionsToRespond.empty()) {
     return;
   }
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -3,18 +3,17 @@
  * 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 "ImageBridgeParent.h"
 #include <stdint.h>                     // for uint64_t, uint32_t
 #include "CompositableHost.h"           // for CompositableParent, Create
 #include "base/message_loop.h"          // for MessageLoop
-#include "base/process.h"               // for ProcessHandle
-#include "base/process_util.h"          // for OpenProcessHandle
+#include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
 #include "base/tracked.h"               // for FROM_HERE
 #include "mozilla/gfx/Point.h"                   // for IntSize
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/layers/CompositableTransactionParent.h"
 #include "mozilla/layers/CompositorParent.h"  // for CompositorParent
@@ -49,42 +48,42 @@ MessageLoop* ImageBridgeParent::sMainLoo
 // defined in CompositorParent.cpp
 CompositorThreadHolder* GetCompositorThreadHolder();
 
 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
                                      Transport* aTransport,
                                      ProcessId aChildProcessId)
   : mMessageLoop(aLoop)
   , mTransport(aTransport)
-  , mChildProcessId(aChildProcessId)
   , mCompositorThreadHolder(GetCompositorThreadHolder())
 {
   MOZ_ASSERT(NS_IsMainThread());
   sMainLoop = MessageLoop::current();
 
   // top-level actors must be destroyed on the main thread.
   SetMessageLoopToPostDestructionTo(sMainLoop);
 
   // creates the map only if it has not been created already, so it is safe
   // with several bridges
   CompositableMap::Create();
   sImageBridges[aChildProcessId] = this;
+  SetOtherProcessId(aChildProcessId);
 }
 
 ImageBridgeParent::~ImageBridgeParent()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (mTransport) {
     MOZ_ASSERT(XRE_GetIOMessageLoop());
     XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
                                      new DeleteTask<Transport>(mTransport));
   }
 
-  sImageBridges.erase(mChildProcessId);
+  sImageBridges.erase(OtherPid());
 }
 
 LayersBackend
 ImageBridgeParent::GetCompositorBackendType() const
 {
   return Compositor::GetBackend();
 }
 
@@ -150,35 +149,30 @@ ImageBridgeParent::RecvUpdateNoSwap(Edit
   bool success = RecvUpdate(Move(aEdits), &noReplies);
   MOZ_ASSERT(noReplies.Length() == 0, "RecvUpdateNoSwap requires a sync Update to carry Edits");
   return success;
 }
 
 static void
 ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
                                   Transport* aTransport,
-                                  base::ProcessHandle aOtherProcess)
+                                  base::ProcessId aOtherPid)
 {
-  aBridge->Open(aTransport, aOtherProcess, XRE_GetIOMessageLoop(), ipc::ParentSide);
+  aBridge->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ParentSide);
 }
 
 /*static*/ PImageBridgeParent*
 ImageBridgeParent::Create(Transport* aTransport, ProcessId aChildProcessId)
 {
-  base::ProcessHandle processHandle;
-  if (!base::OpenProcessHandle(aChildProcessId, &processHandle)) {
-    return nullptr;
-  }
-
   MessageLoop* loop = CompositorParent::CompositorLoop();
   nsRefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport, aChildProcessId);
   bridge->mSelfRef = bridge;
   loop->PostTask(FROM_HERE,
                  NewRunnableFunction(ConnectImageBridgeInParentProcess,
-                                     bridge.get(), aTransport, processHandle));
+                                     bridge.get(), aTransport, aChildProcessId));
   return bridge.get();
 }
 
 bool ImageBridgeParent::RecvWillStop()
 {
   // If there is any texture still alive we have to force it to deallocate the
   // device data (GL textures, etc.) now because shortly after SenStop() returns
   // on the child side the widget will be destroyed along with it's associated
@@ -341,17 +335,17 @@ ImageBridgeParent::CloneToplevel(const I
       return bridge;
     }
   }
   return nullptr;
 }
 
 bool ImageBridgeParent::IsSameProcess() const
 {
-  return OtherProcess() == ipc::kInvalidProcessHandle;
+  return OtherPid() == ipc::kCurrentProcessId;
 }
 
 void
 ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
 {
   mPendingAsyncMessage.push_back(aReply);
 }
 
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -62,17 +62,17 @@ public:
   virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
                                PTextureParent* aTexture,
                                const FenceHandle& aFence) override;
 
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   virtual base::ProcessId GetChildProcessId() override
   {
-    return mChildProcessId;
+    return OtherPid();
   }
 
   // PImageBridge
   virtual bool RecvUpdate(EditArray&& aEdits, EditReplyArray* aReply) override;
   virtual bool RecvUpdateNoSwap(EditArray&& aEdits) override;
 
   virtual bool IsAsync() const override { return true; }
 
@@ -145,18 +145,16 @@ public:
                 base::ProcessHandle aPeerProcess,
                 mozilla::ipc::ProtocolCloneContext* aCtx) override;
 
 private:
   void DeferredDestroy();
 
   MessageLoop* mMessageLoop;
   Transport* mTransport;
-  // Child side's process id.
-  base::ProcessId mChildProcessId;
   // This keeps us alive until ActorDestroy(), at which point we do a
   // deferred destruction of ourselves.
   nsRefPtr<ImageBridgeParent> mSelfRef;
 
   /**
    * Map of all living ImageBridgeParent instances
    */
   static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -142,23 +142,21 @@ ShadowChild(const OpRaiseToTopChild& op)
 {
   return cast(op.childLayerParent());
 }
 
 //--------------------------------------------------
 // LayerTransactionParent
 LayerTransactionParent::LayerTransactionParent(LayerManagerComposite* aManager,
                                                ShadowLayersManager* aLayersManager,
-                                               uint64_t aId,
-                                               ProcessId aOtherProcess)
+                                               uint64_t aId)
   : mLayerManager(aManager)
   , mShadowLayersManager(aLayersManager)
   , mId(aId)
   , mPendingTransaction(0)
-  , mChildProcessId(aOtherProcess)
   , mDestroyed(false)
   , mIPCOpen(false)
 {
   MOZ_COUNT_CTOR(LayerTransactionParent);
 }
 
 LayerTransactionParent::~LayerTransactionParent()
 {
@@ -624,17 +622,17 @@ LayerTransactionParent::RecvUpdate(Infal
       float severity = (latency - TimeDuration::FromMilliseconds(visualWarningTrigger)).ToMilliseconds() /
                          (4 * visualWarningTrigger);
       if (severity > 1.f) {
         severity = 1.f;
       }
       mLayerManager->VisualFrameWarning(severity);
 #ifdef PR_LOGGING
       PR_LogPrint("LayerTransactionParent::RecvUpdate transaction from process %d took %f ms",
-                  mChildProcessId,
+                  OtherPid(),
                   latency.ToMilliseconds());
 #endif
     }
   }
 
   profiler_tracing("Paint", "LayerTransaction", TRACING_INTERVAL_END);
   return true;
 }
@@ -973,17 +971,17 @@ LayerTransactionParent::RecvChildAsyncMe
 void
 LayerTransactionParent::ActorDestroy(ActorDestroyReason why)
 {
   DestroyAsyncTransactionTrackersHolder();
 }
 
 bool LayerTransactionParent::IsSameProcess() const
 {
-  return OtherProcess() == ipc::kInvalidProcessHandle;
+  return OtherPid() == ipc::kCurrentProcessId;
 }
 
 void
 LayerTransactionParent::SendFenceHandleIfPresent(PTextureParent* aTexture,
                                                  CompositableHost* aCompositableHost)
 {
   RefPtr<TextureHost> texture = TextureHost::AsTextureHost(aTexture);
   if (!texture) {
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -42,18 +42,17 @@ class LayerTransactionParent final : pub
   typedef InfallibleTArray<Edit> EditArray;
   typedef InfallibleTArray<EditReply> EditReplyArray;
   typedef InfallibleTArray<AsyncChildMessageData> AsyncChildMessageArray;
   typedef InfallibleTArray<PluginWindowData> PluginsArray;
 
 public:
   LayerTransactionParent(LayerManagerComposite* aManager,
                          ShadowLayersManager* aLayersManager,
-                         uint64_t aId,
-                         ProcessId aOtherProcess);
+                         uint64_t aId);
 
 protected:
   ~LayerTransactionParent();
 
 public:
   void Destroy();
 
   LayerManagerComposite* layer_manager() const { return mLayerManager; }
@@ -93,17 +92,17 @@ public:
   virtual void SendFenceHandle(AsyncTransactionTracker* aTracker,
                                PTextureParent* aTexture,
                                const FenceHandle& aFence) override;
 
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   virtual base::ProcessId GetChildProcessId() override
   {
-    return mChildProcessId;
+    return OtherPid();
   }
 
   virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) override;
 
 protected:
   virtual bool RecvShutdown() override;
 
   virtual bool RecvUpdate(EditArray&& cset,
@@ -196,19 +195,16 @@ private:
   // send us layer transactions.  We want to ignore those transactions
   // because they refer to "zombie layers" on this side.  So, we track
   // that state with |mDestroyed|.  This is similar to, but separate
   // from, |mLayerManager->IsDestroyed()|; we might have had Destroy()
   // called on us but the mLayerManager might not be destroyed, or
   // vice versa.  In both cases though, we want to ignore shadow-layer
   // transactions posted by the child.
 
-  // Child side's process id.
-  base::ProcessId mChildProcessId;
-
   bool mDestroyed;
 
   bool mIPCOpen;
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -733,17 +733,17 @@ ShadowLayerForwarder::IPCOpen() const
 }
 
 bool
 ShadowLayerForwarder::IsSameProcess() const
 {
   if (!HasShadowManager() || !mShadowManager->IPCOpen()) {
     return false;
   }
-  return mShadowManager->OtherProcess() == kInvalidProcessHandle;
+  return mShadowManager->OtherPid() == kCurrentProcessId;
 }
 
 /**
   * We bail out when we have no shadow manager. That can happen when the
   * layer manager is created by the preallocated process.
   * See bug 914843 for details.
   */
 PLayerChild*
--- a/gfx/layers/ipc/SharedBufferManagerChild.cpp
+++ b/gfx/layers/ipc/SharedBufferManagerChild.cpp
@@ -91,55 +91,51 @@ void
 SharedBufferManagerChild::StartUp()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
   SharedBufferManagerChild::StartUpOnThread(new base::Thread("BufferMgrChild"));
 }
 
 static void
 ConnectSharedBufferManagerInChildProcess(mozilla::ipc::Transport* aTransport,
-                                         base::ProcessHandle aOtherProcess)
+                                         base::ProcessId aOtherPid)
 {
   // Bind the IPC channel to the shared buffer manager thread.
-  SharedBufferManagerChild::sSharedBufferManagerChildSingleton->Open(aTransport, aOtherProcess,
+  SharedBufferManagerChild::sSharedBufferManagerChildSingleton->Open(aTransport,
+                                                                     aOtherPid,
                                                                      XRE_GetIOMessageLoop(),
                                                                      ipc::ChildSide);
 
 #ifdef MOZ_NUWA_PROCESS
   if (IsNuwaProcess()) {
     SharedBufferManagerChild::sSharedBufferManagerChildThread
       ->message_loop()->PostTask(FROM_HERE,
                                  NewRunnableFunction(NuwaMarkCurrentThread,
                                                      (void (*)(void *))nullptr,
                                                      (void *)nullptr));
   }
 #endif
 }
 
 PSharedBufferManagerChild*
 SharedBufferManagerChild::StartUpInChildProcess(Transport* aTransport,
-                                                base::ProcessId aOtherProcess)
+                                                base::ProcessId aOtherPid)
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
 
-  ProcessHandle processHandle;
-  if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
-    return nullptr;
-  }
-
   sSharedBufferManagerChildThread = new base::Thread("BufferMgrChild");
   if (!sSharedBufferManagerChildThread->Start()) {
     return nullptr;
   }
 
   sSharedBufferManagerChildSingleton = new SharedBufferManagerChild();
   sSharedBufferManagerChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(ConnectSharedBufferManagerInChildProcess,
-                        aTransport, processHandle));
+                        aTransport, aOtherPid));
 
   return sSharedBufferManagerChildSingleton;
 }
 
 void
 SharedBufferManagerChild::ShutDown()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
--- a/gfx/layers/ipc/SharedBufferManagerParent.cpp
+++ b/gfx/layers/ipc/SharedBufferManagerParent.cpp
@@ -1,18 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=2 ts=8 et 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/layers/SharedBufferManagerParent.h"
 #include "base/message_loop.h"          // for MessageLoop
-#include "base/process.h"               // for ProcessHandle
-#include "base/process_util.h"          // for OpenProcessHandle
+#include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
 #include "base/tracked.h"               // for FROM_HERE
 #include "base/thread.h"
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
 #include "mozilla/UniquePtr.h"          // for UniquePtr
 #include "mozilla/unused.h"
@@ -174,39 +173,36 @@ SharedBufferManagerParent::ActorDestroy(
   DeleteSharedBufferManagerParentTask* task =
     new DeleteSharedBufferManagerParentTask(UniquePtr<SharedBufferManagerParent>(this));
   mMainMessageLoop->PostTask(FROM_HERE, task);
 }
 
 static void
 ConnectSharedBufferManagerInParentProcess(SharedBufferManagerParent* aManager,
                                           Transport* aTransport,
-                                          base::ProcessHandle aOtherProcess)
+                                          base::ProcessId aOtherPid)
 {
-  aManager->Open(aTransport, aOtherProcess, XRE_GetIOMessageLoop(), ipc::ParentSide);
+  aManager->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ParentSide);
 }
 
-PSharedBufferManagerParent* SharedBufferManagerParent::Create(Transport* aTransport, ProcessId aOtherProcess)
+PSharedBufferManagerParent* SharedBufferManagerParent::Create(Transport* aTransport,
+                                                              ProcessId aOtherPid)
 {
-  ProcessHandle processHandle;
-  if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
-    return nullptr;
-  }
   base::Thread* thread = nullptr;
   char thrname[128];
-  base::snprintf(thrname, 128, "BufMgrParent#%d", aOtherProcess);
+  base::snprintf(thrname, 128, "BufMgrParent#%d", aOtherPid);
   thread = new base::Thread(thrname);
 
-  SharedBufferManagerParent* manager = new SharedBufferManagerParent(aTransport, aOtherProcess, thread);
+  SharedBufferManagerParent* manager = new SharedBufferManagerParent(aTransport, aOtherPid, thread);
   if (!thread->IsRunning()) {
     thread->Start();
   }
   thread->message_loop()->PostTask(FROM_HERE,
                                    NewRunnableFunction(ConnectSharedBufferManagerInParentProcess,
-                                                       manager, aTransport, processHandle));
+                                                       manager, aTransport, aOtherPid));
   return manager;
 }
 
 bool SharedBufferManagerParent::RecvAllocateGrallocBuffer(const IntSize& aSize, const uint32_t& aFormat, const uint32_t& aUsage, mozilla::layers::MaybeMagicGrallocBufferHandle* aHandle)
 {
 #ifdef MOZ_HAVE_SURFACEDESCRIPTORGRALLOC
 
   *aHandle = null_t();
--- a/ipc/chromium/src/base/process_util_win.cc
+++ b/ipc/chromium/src/base/process_util_win.cc
@@ -69,33 +69,35 @@ ProcessHandle GetCurrentProcessHandle() 
 bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
   // TODO(phajdan.jr): Take even more permissions out of this list.
   ProcessHandle result = OpenProcess(PROCESS_DUP_HANDLE |
                                          PROCESS_TERMINATE |
                                          PROCESS_QUERY_INFORMATION |
                                          SYNCHRONIZE,
                                      FALSE, pid);
 
-  if (result == INVALID_HANDLE_VALUE)
+  if (result == NULL) {
     return false;
+  }
 
   *handle = result;
   return true;
 }
 
 bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
   ProcessHandle result = OpenProcess(PROCESS_DUP_HANDLE |
                                          PROCESS_TERMINATE |
                                          PROCESS_QUERY_INFORMATION |
                                          PROCESS_VM_READ |
                                          SYNCHRONIZE,
                                      FALSE, pid);
 
-  if (result == INVALID_HANDLE_VALUE)
+  if (result == NULL) {
     return false;
+  }
 
   *handle = result;
   return true;
 }
 
 void CloseProcessHandle(ProcessHandle process) {
   // closing a handle twice on Windows can be catastrophic - after the first
   // close the handle value may be reused, so the second close will kill that
--- a/ipc/chromium/src/base/shared_memory.h
+++ b/ipc/chromium/src/base/shared_memory.h
@@ -119,30 +119,30 @@ class SharedMemory {
   void Close();
 
   // Share the shared memory to another process.  Attempts
   // to create a platform-specific new_handle which can be
   // used in a remote process to access the shared memory
   // file.  new_handle is an ouput parameter to receive
   // the handle for use in the remote process.
   // Returns true on success, false otherwise.
-  bool ShareToProcess(base::ProcessHandle process,
+  bool ShareToProcess(base::ProcessId target_pid,
                       SharedMemoryHandle* new_handle) {
-    return ShareToProcessCommon(process, new_handle, false);
+    return ShareToProcessCommon(target_pid, new_handle, false);
   }
 
   // Logically equivalent to:
   //   bool ok = ShareToProcess(process, new_handle);
   //   Close();
   //   return ok;
   // Note that the memory is unmapped by calling this method, regardless of the
   // return value.
-  bool GiveToProcess(ProcessHandle process,
+  bool GiveToProcess(ProcessId target_pid,
                      SharedMemoryHandle* new_handle) {
-    return ShareToProcessCommon(process, new_handle, true);
+    return ShareToProcessCommon(target_pid, new_handle, true);
   }
 
   // Lock the shared memory.
   // This is a cross-process lock which may be recursively
   // locked by the same thread.
   // TODO(port):
   // WARNING: on POSIX the lock only works across processes, not
   // across threads.  2 threads in the same process can both grab the
@@ -157,17 +157,17 @@ class SharedMemory {
  private:
 #if defined(OS_POSIX)
   bool CreateOrOpen(const std::wstring &name, int posix_flags, size_t size);
   bool FilenameForMemoryName(const std::wstring &memname,
                              std::wstring *filename);
   void LockOrUnlockCommon(int function);
 
 #endif
-  bool ShareToProcessCommon(ProcessHandle process,
+  bool ShareToProcessCommon(ProcessId target_pid,
                             SharedMemoryHandle* new_handle,
                             bool close_self);
 
 #if defined(OS_WIN)
   std::wstring       name_;
   HANDLE             mapped_file_;
 #elif defined(OS_POSIX)
   int                mapped_file_;
--- a/ipc/chromium/src/base/shared_memory_posix.cc
+++ b/ipc/chromium/src/base/shared_memory_posix.cc
@@ -248,17 +248,17 @@ bool SharedMemory::Unmap() {
     return false;
 
   munmap(memory_, max_size_);
   memory_ = NULL;
   max_size_ = 0;
   return true;
 }
 
-bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
+bool SharedMemory::ShareToProcessCommon(ProcessId processId,
                                         SharedMemoryHandle *new_handle,
                                         bool close_self) {
   const int new_fd = dup(mapped_file_);
   DCHECK(new_fd >= -1);
   new_handle->fd = new_fd;
   new_handle->auto_close = true;
 
   if (close_self)
--- a/ipc/chromium/src/base/shared_memory_win.cc
+++ b/ipc/chromium/src/base/shared_memory_win.cc
@@ -2,16 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "base/shared_memory.h"
 
 #include "base/logging.h"
 #include "base/win_util.h"
 #include "base/string_util.h"
+#include "mozilla/ipc/ProtocolUtils.h"
 
 namespace base {
 
 SharedMemory::SharedMemory()
     : mapped_file_(NULL),
       memory_(NULL),
       read_only_(false),
       max_size_(0),
@@ -113,41 +114,43 @@ bool SharedMemory::Unmap() {
   if (memory_ == NULL)
     return false;
 
   UnmapViewOfFile(memory_);
   memory_ = NULL;
   return true;
 }
 
-bool SharedMemory::ShareToProcessCommon(ProcessHandle process,
+bool SharedMemory::ShareToProcessCommon(ProcessId processId,
                                         SharedMemoryHandle *new_handle,
                                         bool close_self) {
   *new_handle = 0;
   DWORD access = STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ;
   DWORD options = 0;
   HANDLE mapped_file = mapped_file_;
   HANDLE result;
   if (!read_only_)
     access |= FILE_MAP_WRITE;
   if (close_self) {
     // DUPLICATE_CLOSE_SOURCE causes DuplicateHandle to close mapped_file.
     options = DUPLICATE_CLOSE_SOURCE;
     mapped_file_ = NULL;
     Unmap();
   }
 
-  if (process == GetCurrentProcess() && close_self) {
+  if (processId == GetCurrentProcId() && close_self) {
     *new_handle = mapped_file;
     return true;
   }
 
-  if (!DuplicateHandle(GetCurrentProcess(), mapped_file, process,
-      &result, access, FALSE, options))
+  if (!mozilla::ipc::DuplicateHandle(mapped_file, processId, &result, access,
+                                     options)) {
     return false;
+  }
+
   *new_handle = result;
   return true;
 }
 
 
 void SharedMemory::Close() {
   if (memory_ != NULL) {
     UnmapViewOfFile(memory_);
--- a/ipc/glue/BackgroundImpl.cpp
+++ b/ipc/glue/BackgroundImpl.cpp
@@ -132,19 +132,16 @@ private:
     {
       AssertIsInMainProcess();
       AssertIsOnMainThread();
       MOZ_ASSERT(aThread);
       MOZ_ASSERT(aLiveActors);
     }
   };
 
-  // A handle that is invalid on any platform.
-  static const ProcessHandle kInvalidProcessHandle;
-
   // The length of time we will wait at shutdown for all actors to clean
   // themselves up before forcing them to be destroyed.
   static const uint32_t kShutdownTimerDelayMS = 10000;
 
   // This is only modified on the main thread. It is null if the thread does not
   // exist or is shutting down.
   static StaticRefPtr<nsIThread> sBackgroundThread;
 
@@ -234,17 +231,17 @@ private:
   // Forwarded from BackgroundParent.
   static intptr_t
   GetRawContentParentForComparison(PBackgroundParent* aBackgroundActor);
 
   // Forwarded from BackgroundParent.
   static PBackgroundParent*
   Alloc(ContentParent* aContent,
         Transport* aTransport,
-        ProcessId aOtherProcess);
+        ProcessId aOtherPid);
 
   static bool
   CreateBackgroundThread();
 
   static void
   ShutdownBackgroundThread();
 
   static void
@@ -252,18 +249,16 @@ private:
 
   // For same-process actors.
   ParentImpl()
   : mTransport(nullptr), mLiveActorArray(nullptr), mIsOtherProcessActor(false),
     mActorDestroyed(false)
   {
     AssertIsInMainProcess();
     AssertIsOnMainThread();
-
-    SetOtherProcess(kInvalidProcessHandle);
   }
 
   // For other-process actors.
   ParentImpl(ContentParent* aContent, Transport* aTransport)
   : mContent(aContent), mTransport(aTransport), mLiveActorArray(nullptr),
     mIsOtherProcessActor(true), mActorDestroyed(false)
   {
     AssertIsInMainProcess();
@@ -404,17 +399,17 @@ public:
 
 private:
   // Forwarded from BackgroundChild.
   static void
   Startup();
 
   // Forwarded from BackgroundChild.
   static PBackgroundChild*
-  Alloc(Transport* aTransport, ProcessId aOtherProcess);
+  Alloc(Transport* aTransport, ProcessId aOtherPid);
 
   // Forwarded from BackgroundChild.
   static PBackgroundChild*
   GetForCurrentThread();
 
   // Forwarded from BackgroundChild.
   static bool
   GetOrCreateForCurrentThread(nsIIPCBackgroundChildCreateCallback* aCallback);
@@ -590,25 +585,25 @@ private:
 
   NS_DECL_NSIRUNNABLE
 };
 
 class ParentImpl::ConnectActorRunnable final : public nsRunnable
 {
   nsRefPtr<ParentImpl> mActor;
   Transport* mTransport;
-  ProcessHandle mProcessHandle;
+  ProcessId mOtherPid;
   nsTArray<ParentImpl*>* mLiveActorArray;
 
 public:
   ConnectActorRunnable(ParentImpl* aActor,
                        Transport* aTransport,
-                       ProcessHandle aProcessHandle,
+                       ProcessId aOtherPid,
                        nsTArray<ParentImpl*>* aLiveActorArray)
-  : mActor(aActor), mTransport(aTransport), mProcessHandle(aProcessHandle),
+  : mActor(aActor), mTransport(aTransport), mOtherPid(aOtherPid),
     mLiveActorArray(aLiveActorArray)
   {
     AssertIsInMainProcess();
     AssertIsOnMainThread();
     MOZ_ASSERT(aActor);
     MOZ_ASSERT(aTransport);
     MOZ_ASSERT(aLiveActorArray);
   }
@@ -744,24 +739,24 @@ protected:
 
   NS_DECL_NSIRUNNABLE
 };
 
 class ChildImpl::OpenChildProcessActorRunnable final : public nsRunnable
 {
   nsRefPtr<ChildImpl> mActor;
   nsAutoPtr<Transport> mTransport;
-  ProcessHandle mProcessHandle;
+  ProcessId mOtherPid;
 
 public:
   OpenChildProcessActorRunnable(already_AddRefed<ChildImpl>&& aActor,
                                 Transport* aTransport,
-                                ProcessHandle aProcessHandle)
+                                ProcessId aOtherPid)
   : mActor(aActor), mTransport(aTransport),
-    mProcessHandle(aProcessHandle)
+    mOtherPid(aOtherPid)
   {
     AssertIsOnMainThread();
     MOZ_ASSERT(mActor);
     MOZ_ASSERT(aTransport);
   }
 
   NS_DECL_ISUPPORTS_INHERITED
 
@@ -871,37 +866,37 @@ BackgroundParent::GetRawContentParentFor
 {
   return ParentImpl::GetRawContentParentForComparison(aBackgroundActor);
 }
 
 // static
 PBackgroundParent*
 BackgroundParent::Alloc(ContentParent* aContent,
                         Transport* aTransport,
-                        ProcessId aOtherProcess)
+                        ProcessId aOtherPid)
 {
-  return ParentImpl::Alloc(aContent, aTransport, aOtherProcess);
+  return ParentImpl::Alloc(aContent, aTransport, aOtherPid);
 }
 
 // -----------------------------------------------------------------------------
 // BackgroundChild Public Methods
 // -----------------------------------------------------------------------------
 
 // static
 void
 BackgroundChild::Startup()
 {
   ChildImpl::Startup();
 }
 
 // static
 PBackgroundChild*
-BackgroundChild::Alloc(Transport* aTransport, ProcessId aOtherProcess)
+BackgroundChild::Alloc(Transport* aTransport, ProcessId aOtherPid)
 {
-  return ChildImpl::Alloc(aTransport, aOtherProcess);
+  return ChildImpl::Alloc(aTransport, aOtherPid);
 }
 
 // static
 PBackgroundChild*
 BackgroundChild::GetForCurrentThread()
 {
   return ChildImpl::GetForCurrentThread();
 }
@@ -954,23 +949,16 @@ BackgroundChildImpl::GetThreadLocalForCu
 {
   return ChildImpl::GetThreadLocalForCurrentThread();
 }
 
 // -----------------------------------------------------------------------------
 // ParentImpl Static Members
 // -----------------------------------------------------------------------------
 
-const ParentImpl::ProcessHandle ParentImpl::kInvalidProcessHandle =
-#ifdef XP_WIN
-  ProcessHandle(INVALID_HANDLE_VALUE);
-#else
-  ProcessHandle(-1);
-#endif
-
 StaticRefPtr<nsIThread> ParentImpl::sBackgroundThread;
 
 nsTArray<ParentImpl*>* ParentImpl::sLiveActorsForBackgroundThread;
 
 StaticRefPtr<nsITimer> ParentImpl::sShutdownTimer;
 
 Atomic<PRThread*> ParentImpl::sBackgroundPRThread;
 
@@ -1057,41 +1045,35 @@ ParentImpl::GetRawContentParentForCompar
 
   return intptr_t(static_cast<nsIContentParent*>(actor->mContent.get()));
 }
 
 // static
 PBackgroundParent*
 ParentImpl::Alloc(ContentParent* aContent,
                   Transport* aTransport,
-                  ProcessId aOtherProcess)
+                  ProcessId aOtherPid)
 {
   AssertIsInMainProcess();
   AssertIsOnMainThread();
   MOZ_ASSERT(aTransport);
 
-  ProcessHandle processHandle;
-  if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
-    // Process has already died?
-    return nullptr;
-  }
-
   if (!sBackgroundThread && !CreateBackgroundThread()) {
     NS_WARNING("Failed to create background thread!");
     return nullptr;
   }
 
   MOZ_ASSERT(sLiveActorsForBackgroundThread);
 
   sLiveActorCount++;
 
   nsRefPtr<ParentImpl> actor = new ParentImpl(aContent, aTransport);
 
   nsCOMPtr<nsIRunnable> connectRunnable =
-    new ConnectActorRunnable(actor, aTransport, processHandle,
+    new ConnectActorRunnable(actor, aTransport, aOtherPid,
                              sLiveActorsForBackgroundThread);
 
   if (NS_FAILED(sBackgroundThread->Dispatch(connectRunnable,
                                             NS_DISPATCH_NORMAL))) {
     NS_WARNING("Failed to dispatch connect runnable!");
 
     MOZ_ASSERT(sLiveActorCount);
     sLiveActorCount--;
@@ -1322,24 +1304,16 @@ ParentImpl::MainThreadActorDestroy()
   MOZ_ASSERT_IF(!mIsOtherProcessActor, !mTransport);
 
   if (mTransport) {
     XRE_GetIOMessageLoop()->PostTask(FROM_HERE,
                                      new DeleteTask<Transport>(mTransport));
     mTransport = nullptr;
   }
 
-  ProcessHandle otherProcess = OtherProcess();
-  if (otherProcess != kInvalidProcessHandle) {
-    base::CloseProcessHandle(otherProcess);
-#ifdef DEBUG
-    SetOtherProcess(kInvalidProcessHandle);
-#endif
-  }
-
   mContent = nullptr;
 
   MOZ_ASSERT(sLiveActorCount);
   sLiveActorCount--;
 
   // This may be the last reference!
   Release();
 }
@@ -1580,18 +1554,17 @@ ParentImpl::ConnectActorRunnable::Run()
   AssertIsInMainProcess();
   AssertIsOnBackgroundThread();
 
   // Transfer ownership to this thread. If Open() fails then we will release
   // this reference in Destroy.
   ParentImpl* actor;
   mActor.forget(&actor);
 
-  if (!actor->Open(mTransport, mProcessHandle, XRE_GetIOMessageLoop(),
-                   ParentSide)) {
+  if (!actor->Open(mTransport, mOtherPid, XRE_GetIOMessageLoop(), ParentSide)) {
     actor->Destroy();
     return NS_ERROR_FAILURE;
   }
 
   actor->SetLiveActorArray(mLiveActorArray);
 
   return NS_OK;
 }
@@ -1653,41 +1626,36 @@ ChildImpl::Shutdown()
   }
 
   DebugOnly<PRStatus> status = PR_SetThreadPrivate(sThreadLocalIndex, nullptr);
   MOZ_ASSERT(status == PR_SUCCESS);
 }
 
 // static
 PBackgroundChild*
-ChildImpl::Alloc(Transport* aTransport, ProcessId aOtherProcess)
+ChildImpl::Alloc(Transport* aTransport, ProcessId aOtherPid)
 {
   AssertIsInChildProcess();
   AssertIsOnMainThread();
   MOZ_ASSERT(aTransport);
   MOZ_ASSERT(sPendingTargets);
   MOZ_ASSERT(!sPendingTargets->IsEmpty());
 
   nsCOMPtr<nsIEventTarget> eventTarget;
   sPendingTargets->ElementAt(0).swap(eventTarget);
 
   sPendingTargets->RemoveElementAt(0);
 
-  ProcessHandle processHandle;
-  if (!base::OpenProcessHandle(aOtherProcess, &processHandle)) {
-    MOZ_CRASH("Failed to open process handle!");
-  }
-
   nsRefPtr<ChildImpl> actor = new ChildImpl();
 
   ChildImpl* weakActor = actor;
 
   nsCOMPtr<nsIRunnable> openRunnable =
     new OpenChildProcessActorRunnable(actor.forget(), aTransport,
-                                      processHandle);
+                                      aOtherPid);
   if (NS_FAILED(eventTarget->Dispatch(openRunnable, NS_DISPATCH_NORMAL))) {
     MOZ_CRASH("Failed to dispatch OpenActorRunnable!");
   }
 
   // This value is only checked against null to determine success/failure, so
   // there is no need to worry about the reference count here.
   return weakActor;
 }
@@ -1910,17 +1878,17 @@ ChildImpl::OpenChildProcessActorRunnable
     ChildImpl::GetNextCallback();
   MOZ_ASSERT(callback,
              "There should be at least one callback when first creating the "
              "actor!");
 
   nsRefPtr<ChildImpl> strongActor;
   mActor.swap(strongActor);
 
-  if (!strongActor->Open(mTransport.forget(), mProcessHandle,
+  if (!strongActor->Open(mTransport.forget(), mOtherPid,
                          XRE_GetIOMessageLoop(), ChildSide)) {
     CRASH_IN_CHILD_PROCESS("Failed to open ChildImpl!");
 
     while (callback) {
       callback->ActorFailed();
       callback = ChildImpl::GetNextCallback();
     }
 
@@ -1983,16 +1951,19 @@ ChildImpl::OpenMainProcessActorRunnable:
     while (callback) {
       callback->ActorFailed();
       callback = ChildImpl::GetNextCallback();
     }
 
     return NS_OK;
   }
 
+  // Make sure the parent knows it is same process.
+  parentActor->SetOtherProcessId(kCurrentProcessId);
+
   // Now that Open() has succeeded transfer the ownership of the actors to IPDL.
   unused << parentActor.forget();
 
   auto threadLocalInfo =
     static_cast<ThreadLocalInfo*>(PR_GetThreadPrivate(sThreadLocalIndex));
 
   MOZ_ASSERT(threadLocalInfo);
   MOZ_ASSERT(!threadLocalInfo->mActor);
--- a/ipc/glue/CrossProcessMutex.h
+++ b/ipc/glue/CrossProcessMutex.h
@@ -84,17 +84,17 @@ public:
 
   /**
    * ShareToProcess
    * This function is called to generate a serializable structure that can
    * be sent to the specified process and opened on the other side.
    *
    * @returns A handle that can be shared to another process
    */
-  CrossProcessMutexHandle ShareToProcess(base::ProcessHandle aTarget);
+  CrossProcessMutexHandle ShareToProcess(base::ProcessId aTargetPid);
 
 private:
   friend struct IPC::ParamTraits<CrossProcessMutex>;
 
   CrossProcessMutex();
   CrossProcessMutex(const CrossProcessMutex&);
   CrossProcessMutex &operator=(const CrossProcessMutex&);
 
--- a/ipc/glue/CrossProcessMutex_posix.cpp
+++ b/ipc/glue/CrossProcessMutex_posix.cpp
@@ -133,20 +133,20 @@ CrossProcessMutex::Lock()
 void
 CrossProcessMutex::Unlock()
 {
   MOZ_ASSERT(*mCount > 0, "Attempting to unlock mutex with zero ref count");
   pthread_mutex_unlock(mMutex);
 }
 
 CrossProcessMutexHandle
-CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle)
+CrossProcessMutex::ShareToProcess(base::ProcessId aTargetPid)
 {
   CrossProcessMutexHandle result = ipc::SharedMemoryBasic::NULLHandle();
 
-  if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aHandle, &result)) {
+  if (mSharedBuffer && !mSharedBuffer->ShareToProcess(aTargetPid, &result)) {
     MOZ_CRASH();
   }
 
   return result;
 }
 
 }
--- a/ipc/glue/CrossProcessMutex_unimplemented.cpp
+++ b/ipc/glue/CrossProcessMutex_unimplemented.cpp
@@ -32,15 +32,15 @@ CrossProcessMutex::Lock()
 
 void
 CrossProcessMutex::Unlock()
 {
   NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform - woah! We should've aborted by now!");
 }
 
 CrossProcessMutexHandle
-CrossProcessMutex::ShareToProcess(base::ProcessHandle aHandle)
+CrossProcessMutex::ShareToProcess(base::ProcessId aTargetPid)
 {
   NS_RUNTIMEABORT("Cross-process mutices not allowed on this platform - woah! We should've aborted by now!");
   return 0;
 }
 
 }
--- a/ipc/glue/CrossProcessMutex_windows.cpp
+++ b/ipc/glue/CrossProcessMutex_windows.cpp
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include <windows.h>
 
 #include "base/process_util.h"
 #include "CrossProcessMutex.h"
 #include "nsDebug.h"
 #include "nsISupportsImpl.h"
+#include "ProtocolUtils.h"
 
 using base::GetCurrentProcessHandle;
 using base::ProcessHandle;
 
 namespace mozilla {
 
 CrossProcessMutex::CrossProcessMutex(const char*)
 {
@@ -54,22 +55,21 @@ CrossProcessMutex::Lock()
 void
 CrossProcessMutex::Unlock()
 {
   NS_ASSERTION(mMutex, "Improper construction of mutex.");
   ::ReleaseMutex(mMutex);
 }
 
 CrossProcessMutexHandle
-CrossProcessMutex::ShareToProcess(ProcessHandle aHandle)
+CrossProcessMutex::ShareToProcess(base::ProcessId aTargetPid)
 {
   HANDLE newHandle;
-  bool succeeded = ::DuplicateHandle(GetCurrentProcessHandle(),
-                                     mMutex, aHandle, &newHandle,
-                                     0, FALSE, DUPLICATE_SAME_ACCESS);
+  bool succeeded = ipc::DuplicateHandle(mMutex, aTargetPid, &newHandle,
+                                        0, DUPLICATE_SAME_ACCESS);
 
   if (!succeeded) {
     return nullptr;
   }
 
   return newHandle;
 }
 
--- a/ipc/glue/FileDescriptor.cpp
+++ b/ipc/glue/FileDescriptor.cpp
@@ -5,16 +5,17 @@
 #include "FileDescriptor.h"
 
 #include "mozilla/Assertions.h"
 #include "nsDebug.h"
 
 #ifdef XP_WIN
 
 #include <windows.h>
+#include "ProtocolUtils.h"
 #define INVALID_HANDLE INVALID_HANDLE_VALUE
 
 #else // XP_WIN
 
 #include <unistd.h>
 
 #ifndef OS_POSIX
 #define OS_POSIX
@@ -43,18 +44,18 @@ void
 FileDescriptor::DuplicateInCurrentProcess(PlatformHandleType aHandle)
 {
   MOZ_ASSERT_IF(mHandleCreatedByOtherProcess && IsValid(),
                 mHandleCreatedByOtherProcessWasUsed);
 
   if (IsValid(aHandle)) {
     PlatformHandleType newHandle;
 #ifdef XP_WIN
-    if (DuplicateHandle(GetCurrentProcess(), aHandle, GetCurrentProcess(),
-                        &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+    if (::DuplicateHandle(GetCurrentProcess(), aHandle, GetCurrentProcess(),
+                          &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
 #else // XP_WIN
     if ((newHandle = dup(aHandle)) != INVALID_HANDLE) {
 #endif
       mHandle = newHandle;
       return;
     }
     NS_WARNING("Failed to duplicate file handle for current process!");
   }
@@ -82,23 +83,23 @@ FileDescriptor::CloseCurrentProcessHandl
     HANDLE_EINTR(close(mHandle));
 #endif
     mHandle = INVALID_HANDLE;
   }
 }
 
 FileDescriptor::PickleType
 FileDescriptor::ShareTo(const FileDescriptor::IPDLPrivate&,
-                        FileDescriptor::ProcessHandle aOtherProcess) const
+                        FileDescriptor::ProcessId aTargetPid) const
 {
   PlatformHandleType newHandle;
 #ifdef XP_WIN
   if (IsValid()) {
-    if (DuplicateHandle(GetCurrentProcess(), mHandle, aOtherProcess,
-                        &newHandle, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
+    if (mozilla::ipc::DuplicateHandle(mHandle, aTargetPid, &newHandle, 0,
+                                      DUPLICATE_SAME_ACCESS)) {
       return newHandle;
     }
     NS_WARNING("Failed to duplicate file handle for other process!");
   }
   return INVALID_HANDLE;
 #else // XP_WIN
   if (IsValid()) {
     newHandle = dup(mHandle);
--- a/ipc/glue/FileDescriptor.h
+++ b/ipc/glue/FileDescriptor.h
@@ -30,17 +30,17 @@ namespace ipc {
 //
 // To use this class add 'FileDescriptor' as an argument in the IPDL protocol
 // and then pass a file descriptor from C++ to the Call/Send method. The
 // Answer/Recv method will receive a FileDescriptor& on which PlatformHandle()
 // can be called to return the platform file handle.
 class FileDescriptor
 {
 public:
-  typedef base::ProcessHandle ProcessHandle;
+  typedef base::ProcessId ProcessId;
 
 #ifdef XP_WIN
   typedef HANDLE PlatformHandleType;
   typedef HANDLE PickleType;
 #else
   typedef int PlatformHandleType;
   typedef base::FileDescriptor PickleType;
 #endif
@@ -84,17 +84,17 @@ public:
     Assign(aOther);
     return *this;
   }
 
   // Performs platform-specific actions to duplicate mHandle in the other
   // process (e.g. dup() on POSIX, DuplicateHandle() on Windows). Returns a
   // pickled value that can be passed to the other process via IPC.
   PickleType
-  ShareTo(const IPDLPrivate&, ProcessHandle aOtherProcess) const;
+  ShareTo(const IPDLPrivate&, ProcessId aTargetPid) const;
 
   // Tests mHandle against a well-known invalid platform-specific file handle
   // (e.g. -1 on POSIX, INVALID_HANDLE_VALUE on Windows).
   bool
   IsValid() const
   {
     return IsValid(mHandle);
   }
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -24,16 +24,17 @@
 #include "nsExceptionHandler.h"
 
 #include "nsDirectoryServiceDefs.h"
 #include "nsIFile.h"
 
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/Omnijar.h"
+#include "ProtocolUtils.h"
 #include <sys/stat.h>
 
 #ifdef XP_WIN
 #include "nsIWinTaskbar.h"
 #define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
 
 #if defined(MOZ_SANDBOX)
 #include "mozilla/Preferences.h"
@@ -423,16 +424,21 @@ GeckoChildProcessHost::Join()
   // If this fails, there's nothing we can do.
   base::KillProcess(mChildProcessHandle, 0, /*wait*/true);
   SetAlreadyDead();
 }
 
 void
 GeckoChildProcessHost::SetAlreadyDead()
 {
+  if (mChildProcessHandle &&
+      mChildProcessHandle != kInvalidProcessHandle) {
+    base::CloseProcessHandle(mChildProcessHandle);
+  }
+
   mChildProcessHandle = 0;
 }
 
 int32_t GeckoChildProcessHost::mChildCounter = 0;
 
 //
 // Wrapper function for handling GECKO_SEPARATE_NSPR_LOGS
 //
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -101,28 +101,16 @@ public:
   }
 
   // Returns a "borrowed" handle to the child process - the handle returned
   // by this function must not be closed by the caller.
   ProcessHandle GetChildProcessHandle() {
     return mChildProcessHandle;
   }
 
-  // Returns an "owned" handle to the child process - the handle returned
-  // by this function must be closed by the caller.
-  ProcessHandle GetOwnedChildProcessHandle() {
-    ProcessHandle handle;
-    // We use OpenPrivilegedProcessHandle as that is where our
-    // mChildProcessHandle initially came from.
-    bool ok = base::OpenPrivilegedProcessHandle(base::GetProcId(mChildProcessHandle),
-                                                &handle);
-    NS_ASSERTION(ok, "Failed to get owned process handle");
-    return ok ? handle : 0;
-  }
-
   GeckoProcessType GetProcessType() {
     return mProcessType;
   }
 
 #ifdef XP_MACOSX
   task_t GetChildTask() {
     return mChildTask;
   }
--- a/ipc/glue/ProcessChild.cpp
+++ b/ipc/glue/ProcessChild.cpp
@@ -10,20 +10,20 @@
 #include "mozilla/ipc/IOThreadChild.h"
 #include "mozilla/ipc/ProcessChild.h"
 
 namespace mozilla {
 namespace ipc {
 
 ProcessChild* ProcessChild::gProcessChild;
 
-ProcessChild::ProcessChild(ProcessHandle parentHandle)
+ProcessChild::ProcessChild(ProcessId aParentPid)
   : ChildProcess(new IOThreadChild())
   , mUILoop(MessageLoop::current())
-  , mParentHandle(parentHandle)
+  , mParentPid(aParentPid)
 {
   MOZ_ASSERT(mUILoop, "UILoop should be created by now");
   MOZ_ASSERT(!gProcessChild, "should only be one ProcessChild");
   gProcessChild = this;
 }
 
 ProcessChild::~ProcessChild()
 {
--- a/ipc/glue/ProcessChild.h
+++ b/ipc/glue/ProcessChild.h
@@ -17,44 +17,44 @@
 // browser process.  Its code runs on the thread that started in
 // main().
 
 namespace mozilla {
 namespace ipc {
 
 class ProcessChild : public ChildProcess {
 protected:
-  typedef base::ProcessHandle ProcessHandle;
+  typedef base::ProcessId ProcessId;
 
 public:
-  explicit ProcessChild(ProcessHandle parentHandle);
+  explicit ProcessChild(ProcessId aParentPid);
   virtual ~ProcessChild();
 
   virtual bool Init() = 0;
   virtual void CleanUp()
   { }
 
   static MessageLoop* message_loop() {
     return gProcessChild->mUILoop;
   }
 
 protected:
   static ProcessChild* current() {
     return gProcessChild;
   }
 
-  ProcessHandle ParentHandle() {
-    return mParentHandle;
+  ProcessId ParentPid() {
+    return mParentPid;
   }
 
 private:
   static ProcessChild* gProcessChild;
 
   MessageLoop* mUILoop;
-  ProcessHandle mParentHandle;
+  ProcessId mParentPid;
 
   DISALLOW_EVIL_CONSTRUCTORS(ProcessChild);
 };
 
 } // namespace ipc
 } // namespace mozilla
 
 
--- a/ipc/glue/ProtocolUtils.cpp
+++ b/ipc/glue/ProtocolUtils.cpp
@@ -6,20 +6,24 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "base/process_util.h"
 
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"
 
+#if defined(MOZ_SANDBOX) && defined(XP_WIN)
+#define TARGET_SANDBOX_EXPORTS
+#include "mozilla/sandboxTarget.h"
+#endif
+
 using namespace IPC;
 
-using base::GetCurrentProcessHandle;
-using base::GetProcId;
+using base::GetCurrentProcId;
 using base::ProcessHandle;
 using base::ProcessId;
 
 namespace mozilla {
 namespace ipc {
 
 static Atomic<size_t> gNumProtocols;
 static StaticAutoPtr<Mutex> gProtocolMutex;
@@ -179,66 +183,60 @@ public:
     }
     aMsg.EndRead(iter);
     return true;
   }
 };
 
 bool
 Bridge(const PrivateIPDLInterface&,
-       MessageChannel* aParentChannel, ProcessHandle aParentProcess,
-       MessageChannel* aChildChannel, ProcessHandle aChildProcess,
+       MessageChannel* aParentChannel, ProcessId aParentPid,
+       MessageChannel* aChildChannel, ProcessId aChildPid,
        ProtocolId aProtocol, ProtocolId aChildProtocol)
 {
-  ProcessId parentId = GetProcId(aParentProcess);
-  ProcessId childId = GetProcId(aChildProcess);
-  if (!parentId || !childId) {
+  if (!aParentPid || !aChildPid) {
     return false;
   }
 
   TransportDescriptor parentSide, childSide;
-  if (!CreateTransport(aParentProcess, aChildProcess,
-                       &parentSide, &childSide)) {
+  if (!CreateTransport(aParentPid, &parentSide, &childSide)) {
     return false;
   }
 
   if (!aParentChannel->Send(new ChannelOpened(parentSide,
-                                              childId,
+                                              aChildPid,
                                               aProtocol,
                                               IPC::Message::PRIORITY_URGENT)) ||
       !aChildChannel->Send(new ChannelOpened(childSide,
-                                             parentId,
+                                             aParentPid,
                                              aChildProtocol,
                                              IPC::Message::PRIORITY_URGENT))) {
     CloseDescriptor(parentSide);
     CloseDescriptor(childSide);
     return false;
   }
   return true;
 }
 
 bool
 Open(const PrivateIPDLInterface&,
-     MessageChannel* aOpenerChannel, ProcessHandle aOtherProcess,
+     MessageChannel* aOpenerChannel, ProcessId aOtherProcessId,
      Transport::Mode aOpenerMode,
      ProtocolId aProtocol, ProtocolId aChildProtocol)
 {
   bool isParent = (Transport::MODE_SERVER == aOpenerMode);
-  ProcessHandle thisHandle = GetCurrentProcessHandle();
-  ProcessHandle parentHandle = isParent ? thisHandle : aOtherProcess;
-  ProcessHandle childHandle = !isParent ? thisHandle : aOtherProcess;
-  ProcessId parentId = GetProcId(parentHandle);
-  ProcessId childId = GetProcId(childHandle);
+  ProcessId thisPid = GetCurrentProcId();
+  ProcessId parentId = isParent ? thisPid : aOtherProcessId;
+  ProcessId childId = !isParent ? thisPid : aOtherProcessId;
   if (!parentId || !childId) {
     return false;
   }
 
   TransportDescriptor parentSide, childSide;
-  if (!CreateTransport(parentHandle, childHandle,
-                       &parentSide, &childSide)) {
+  if (!CreateTransport(parentId, &parentSide, &childSide)) {
     return false;
   }
 
   Message* parentMsg = new ChannelOpened(parentSide, childId, aProtocol);
   Message* childMsg = new ChannelOpened(childSide, parentId, aChildProtocol);
   nsAutoPtr<Message> messageForUs(isParent ? parentMsg : childMsg);
   nsAutoPtr<Message> messageForOtherSide(!isParent ? parentMsg : childMsg);
   if (!aOpenerChannel->Echo(messageForUs.forget()) ||
@@ -255,42 +253,86 @@ UnpackChannelOpened(const PrivateIPDLInt
                     const Message& aMsg,
                     TransportDescriptor* aTransport,
                     ProcessId* aOtherProcess,
                     ProtocolId* aProtocol)
 {
   return ChannelOpened::Read(aMsg, aTransport, aOtherProcess, aProtocol);
 }
 
+#if defined(XP_WIN)
+bool DuplicateHandle(HANDLE aSourceHandle,
+                     DWORD aTargetProcessId,
+                     HANDLE* aTargetHandle,
+                     DWORD aDesiredAccess,
+                     DWORD aOptions) {
+  // If our process is the target just duplicate the handle.
+  if (aTargetProcessId == kCurrentProcessId) {
+    return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
+                               ::GetCurrentProcess(), aTargetHandle,
+                               aDesiredAccess, false, aOptions);
+
+  }
+
+#if defined(MOZ_SANDBOX)
+  // Try the broker next (will fail if not sandboxed).
+  if (SandboxTarget::Instance()->BrokerDuplicateHandle(aSourceHandle,
+                                                       aTargetProcessId,
+                                                       aTargetHandle,
+                                                       aDesiredAccess,
+                                                       aOptions)) {
+    return true;
+  }
+#endif
+
+  // Finally, see if we already have access to the process.
+  ScopedProcessHandle targetProcess;
+  if (!base::OpenProcessHandle(aTargetProcessId, &targetProcess.rwget())) {
+    return false;
+  }
+
+  return !!::DuplicateHandle(::GetCurrentProcess(), aSourceHandle,
+                              targetProcess, aTargetHandle,
+                              aDesiredAccess, FALSE, aOptions);
+}
+#endif
+
 void
 ProtocolErrorBreakpoint(const char* aMsg)
 {
     // Bugs that generate these error messages can be tough to
     // reproduce.  Log always in the hope that someone finds the error
     // message.
     printf_stderr("IPDL protocol error: %s\n", aMsg);
 }
 
 void
 FatalError(const char* aProtocolName, const char* aMsg,
-           ProcessHandle aHandle, bool aIsParent)
+           ProcessId aOtherPid, bool aIsParent)
 {
   ProtocolErrorBreakpoint(aMsg);
 
   nsAutoCString formattedMessage("IPDL error [");
   formattedMessage.AppendASCII(aProtocolName);
   formattedMessage.AppendLiteral("]: \"");
   formattedMessage.AppendASCII(aMsg);
   if (aIsParent) {
     formattedMessage.AppendLiteral("\". Killing child side as a result.");
     NS_ERROR(formattedMessage.get());
 
-    if (aHandle != kInvalidProcessHandle &&
-        !base::KillProcess(aHandle, base::PROCESS_END_KILLED_BY_USER, false)) {
-      NS_ERROR("May have failed to kill child!");
+    if (aOtherPid != kInvalidProcessId && aOtherPid != kCurrentProcessId) {
+      ScopedProcessHandle otherProcessHandle;
+      if (base::OpenProcessHandle(aOtherPid, &otherProcessHandle.rwget())) {
+        if (!base::KillProcess(otherProcessHandle,
+                               base::PROCESS_END_KILLED_BY_USER, false)) {
+          NS_ERROR("May have failed to kill child!");
+        }
+      } else {
+        NS_ERROR("Failed to open child process when attempting kill.");
+      }
     }
   } else {
     formattedMessage.AppendLiteral("\". abort()ing as a result.");
     NS_RUNTIMEABORT(formattedMessage.get());
   }
 }
 
 } // namespace ipc
--- a/ipc/glue/ProtocolUtils.h
+++ b/ipc/glue/ProtocolUtils.h
@@ -55,19 +55,48 @@ class ContentParent;
 namespace net {
 class NeckoParent;
 }
 
 namespace ipc {
 
 #ifdef XP_WIN
 const base::ProcessHandle kInvalidProcessHandle = INVALID_HANDLE_VALUE;
+
+// In theory, on Windows, this is a valid process ID, but in practice they are
+// currently divisible by four. Process IDs share the kernel handle allocation
+// code and they are guaranteed to be divisible by four.
+// As this could change for process IDs we shouldn't generally rely on this
+// property, however even if that were to change, it seems safe to rely on this
+// particular value never being used.
+const base::ProcessId kInvalidProcessId = kuint32max;
 #else
 const base::ProcessHandle kInvalidProcessHandle = -1;
+const base::ProcessId kInvalidProcessId = -1;
 #endif
+const base::ProcessId kCurrentProcessId = base::GetCurrentProcId();
+
+// Scoped base::ProcessHandle to ensure base::CloseProcessHandle is called.
+struct ScopedProcessHandleTraits
+{
+  typedef base::ProcessHandle type;
+
+  static type empty()
+  {
+    return kInvalidProcessHandle;
+  }
+
+  static void release(type aProcessHandle)
+  {
+    if (aProcessHandle && aProcessHandle != kInvalidProcessHandle) {
+      base::CloseProcessHandle(aProcessHandle);
+    }
+  }
+};
+typedef mozilla::Scoped<ScopedProcessHandleTraits> ScopedProcessHandle;
 
 class ProtocolFdMapping;
 class ProtocolCloneContext;
 
 // Used to pass references to protocol actors across the wire.
 // Actors created on the parent-side have a positive ID, and actors
 // allocated on the child side have a negative ID.
 struct ActorHandle
@@ -129,33 +158,33 @@ public:
     enum ActorDestroyReason {
         FailedConstructor,
         Deletion,
         AncestorDeletion,
         NormalShutdown,
         AbnormalShutdown
     };
 
-    typedef base::ProcessHandle ProcessHandle;
+    typedef base::ProcessId ProcessId;
 
     virtual int32_t Register(ListenerT*) = 0;
     virtual int32_t RegisterID(ListenerT*, int32_t) = 0;
     virtual ListenerT* Lookup(int32_t) = 0;
     virtual void Unregister(int32_t) = 0;
     virtual void RemoveManagee(int32_t, ListenerT*) = 0;
 
     virtual Shmem::SharedMemory* CreateSharedMemory(
         size_t, SharedMemory::SharedMemoryType, bool, int32_t*) = 0;
     virtual bool AdoptSharedMemory(Shmem::SharedMemory*, int32_t*) = 0;
     virtual Shmem::SharedMemory* LookupSharedMemory(int32_t) = 0;
     virtual bool IsTrackingSharedMemory(Shmem::SharedMemory*) = 0;
     virtual bool DestroySharedMemory(Shmem&) = 0;
 
     // XXX odd ducks, acknowledged
-    virtual ProcessHandle OtherProcess() const = 0;
+    virtual ProcessId OtherPid() const = 0;
     virtual MessageChannel* GetIPCChannel() = 0;
 
     // The implementation of function is generated by code generator.
     virtual void CloneManagees(ListenerT* aSource,
                                ProtocolCloneContext* aCtx) = 0;
 };
 
 typedef IPCMessageStart ProtocolId;
@@ -261,35 +290,48 @@ LoggingEnabledFor(const char *aTopLevelP
 #endif
 }
 
 MOZ_NEVER_INLINE void
 ProtocolErrorBreakpoint(const char* aMsg);
 
 MOZ_NEVER_INLINE void
 FatalError(const char* aProtocolName, const char* aMsg,
-           base::ProcessHandle aHandle, bool aIsParent);
+           base::ProcessId aOtherPid, bool aIsParent);
 
 struct PrivateIPDLInterface {};
 
 bool
 Bridge(const PrivateIPDLInterface&,
-       MessageChannel*, base::ProcessHandle, MessageChannel*, base::ProcessHandle,
+       MessageChannel*, base::ProcessId, MessageChannel*, base::ProcessId,
        ProtocolId, ProtocolId);
 
 bool
 Open(const PrivateIPDLInterface&,
-     MessageChannel*, base::ProcessHandle, Transport::Mode,
+     MessageChannel*, base::ProcessId, Transport::Mode,
      ProtocolId, ProtocolId);
 
 bool
 UnpackChannelOpened(const PrivateIPDLInterface&,
                     const IPC::Message&,
                     TransportDescriptor*, base::ProcessId*, ProtocolId*);
 
+#if defined(XP_WIN)
+// This is a restricted version of Windows' DuplicateHandle() function
+// that works inside the sandbox and can send handles but not retrieve
+// them.  Unlike DuplicateHandle(), it takes a process ID rather than
+// a process handle.  It returns true on success, false otherwise.
+bool
+DuplicateHandle(HANDLE aSourceHandle,
+                DWORD aTargetProcessId,
+                HANDLE* aTargetHandle,
+                DWORD aDesiredAccess,
+                DWORD aOptions);
+#endif
+
 } // namespace ipc
 } // namespace mozilla
 
 
 namespace IPC {
 
 template <>
 struct ParamTraits<mozilla::ipc::ActorHandle>
--- a/ipc/glue/SharedMemoryBasic_android.cpp
+++ b/ipc/glue/SharedMemoryBasic_android.cpp
@@ -90,17 +90,17 @@ SharedMemoryBasic::Map(size_t nBytes)
     return false;
   }
 
   Mapped(nBytes);
   return true;
 }
 
 bool
-SharedMemoryBasic::ShareToProcess(base::ProcessHandle/*unused*/,
+SharedMemoryBasic::ShareToProcess(base::ProcessId/*unused*/,
                                   Handle* aNewHandle)
 {
   MOZ_ASSERT(mShmFd >= 0, "Should have been Create()d by now");
 
   int shmfdDup = dup(mShmFd);
   if (-1 == shmfdDup) {
     LogError("ShmemAndroid::ShareToProcess()");
     return false;
--- a/ipc/glue/SharedMemoryBasic_android.h
+++ b/ipc/glue/SharedMemoryBasic_android.h
@@ -48,17 +48,17 @@ public:
     return Handle();
   }
 
   static bool IsHandleValid(const Handle &aHandle)
   {
     return aHandle.fd >= 0;
   }
 
-  bool ShareToProcess(base::ProcessHandle aProcess,
+  bool ShareToProcess(base::ProcessId aProcessId,
                       Handle* aNewHandle);
 
 private:
   ~SharedMemoryBasic();
 
   void Unmap();
   void Destroy();
 
--- a/ipc/glue/SharedMemoryBasic_chromium.h
+++ b/ipc/glue/SharedMemoryBasic_chromium.h
@@ -68,21 +68,21 @@ public:
     return base::SharedMemory::NULLHandle();
   }
 
   static bool IsHandleValid(const Handle &aHandle)
   {
     return base::SharedMemory::IsHandleValid(aHandle);
   }
 
-  bool ShareToProcess(base::ProcessHandle process,
+  bool ShareToProcess(base::ProcessId aProcessId,
                       Handle* new_handle)
   {
     base::SharedMemoryHandle handle;
-    bool ret = mSharedMemory.ShareToProcess(process, &handle);
+    bool ret = mSharedMemory.ShareToProcess(aProcessId, &handle);
     if (ret)
       *new_handle = handle;
     return ret;
   }
 
 private:
   ~SharedMemoryBasic()
   {
--- a/ipc/glue/Shmem.cpp
+++ b/ipc/glue/Shmem.cpp
@@ -608,30 +608,25 @@ Shmem::GetSysVID() const
 #else
   NS_ERROR("Can't call GetSysVID() with no support for SysV shared memory!");
   return -1;                    // not reached
 #endif
 }
 
 IPC::Message*
 Shmem::ShareTo(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
-               base::ProcessHandle aProcess,
+               base::ProcessId aTargetPid,
                int32_t routingId)
 {
   AssertInvariants();
 
-  // kInvalidProcessHandle is used to indicate that it's the same process.
-  if (aProcess == kInvalidProcessHandle) {
-    aProcess = base::GetCurrentProcessHandle();
-  }
-
   if (SharedMemory::TYPE_BASIC == mSegment->Type()) {
     SharedMemoryBasic* seg = static_cast<SharedMemoryBasic*>(mSegment);
     SharedMemoryBasic::Handle handle;
-    if (!seg->ShareToProcess(aProcess, &handle))
+    if (!seg->ShareToProcess(aTargetPid, &handle))
       return nullptr;
 
     return new ShmemCreated(routingId, mId, mSize, handle);
   }
 #ifdef MOZ_HAVE_SHAREDMEMORYSYSV
   else if (SharedMemory::TYPE_SYSV == mSegment->Type()) {
     SharedMemorySysV* seg = static_cast<SharedMemorySysV*>(mSegment);
     return new ShmemCreated(routingId, mId, mSize, seg->GetHandle());
@@ -642,17 +637,17 @@ Shmem::ShareTo(IHadBetterBeIPDLCodeCalli
     return nullptr;
   }
 
   return nullptr;
 }
 
 IPC::Message*
 Shmem::UnshareFrom(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
-                   base::ProcessHandle aProcess,
+                   base::ProcessId aTargetPid,
                    int32_t routingId)
 {
   AssertInvariants();
   return new ShmemDestroyed(routingId, mId);
 }
 
 } // namespace ipc
 } // namespace mozilla
--- a/ipc/glue/Shmem.h
+++ b/ipc/glue/Shmem.h
@@ -210,26 +210,26 @@ public:
         bool aProtect=false);
 
   // Prepare this to be shared with |aProcess|.  Return an IPC message
   // that contains enough information for the other process to map
   // this segment in OpenExisting() below.  Return a new message if
   // successful (owned by the caller), nullptr if not.
   IPC::Message*
   ShareTo(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
-          base::ProcessHandle aProcess,
+          base::ProcessId aTargetPid,
           int32_t routingId);
 
-  // Stop sharing this with |aProcess|.  Return an IPC message that
+  // Stop sharing this with |aTargetPid|.  Return an IPC message that
   // contains enough information for the other process to unmap this
   // segment.  Return a new message if successful (owned by the
   // caller), nullptr if not.
   IPC::Message*
   UnshareFrom(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
-              base::ProcessHandle aProcess,
+              base::ProcessId aTargetPid,
               int32_t routingId);
 
   // Return a SharedMemory instance in this process using the
   // descriptor shared to us by the process that created the
   // underlying OS shmem resource.  The contents of the descriptor
   // depend on the type of SharedMemory that was passed to us.
   static already_AddRefed<SharedMemory>
   OpenExisting(IHadBetterBeIPDLCodeCallingThis_OtherwiseIAmADoodyhead,
--- a/ipc/glue/Transport.h
+++ b/ipc/glue/Transport.h
@@ -19,17 +19,17 @@
 
 namespace mozilla {
 namespace ipc {
 
 class FileDescriptor;
 
 typedef IPC::Channel Transport;
 
-bool CreateTransport(base::ProcessHandle aProcOne, base::ProcessHandle aProcTwo,
+bool CreateTransport(base::ProcessId aProcIdOne,
                      TransportDescriptor* aOne, TransportDescriptor* aTwo);
 
 Transport* OpenDescriptor(const TransportDescriptor& aTd,
                           Transport::Mode aMode);
 
 Transport* OpenDescriptor(const FileDescriptor& aFd,
                           Transport::Mode aMode);
 
--- a/ipc/glue/Transport_posix.cpp
+++ b/ipc/glue/Transport_posix.cpp
@@ -17,17 +17,17 @@
 using namespace std;
 
 using base::ProcessHandle;
 
 namespace mozilla {
 namespace ipc {
 
 bool
-CreateTransport(ProcessHandle /*unused*/, ProcessHandle /*unused*/,
+CreateTransport(base::ProcessId /*unused*/,
                 TransportDescriptor* aOne, TransportDescriptor* aTwo)
 {
   // Gecko doesn't care about this random ID, and the argument to this
   // function isn't really necessary, it can be just any random
   // pointer value
   wstring id = ChildProcessInfo::GenerateRandomChannelID(aOne);
   // Use MODE_SERVER to force creation of the socketpair
   Transport t(id, Transport::MODE_SERVER, nullptr);
--- a/ipc/glue/Transport_win.cpp
+++ b/ipc/glue/Transport_win.cpp
@@ -4,26 +4,27 @@
 /* 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 "base/message_loop.h"
 #include "chrome/common/child_process_info.h"
 
 #include "mozilla/ipc/Transport.h"
+#include "mozilla/ipc/ProtocolUtils.h"
 
 using namespace std;
 
 using base::ProcessHandle;
 
 namespace mozilla {
 namespace ipc {
 
 bool
-CreateTransport(ProcessHandle aProcOne, ProcessHandle /*unused*/,
+CreateTransport(base::ProcessId aProcIdOne,
                 TransportDescriptor* aOne, TransportDescriptor* aTwo)
 {
   // This id is used to name the IPC pipe.  The pointer passed to this
   // function isn't significant.
   wstring id = ChildProcessInfo::GenerateRandomChannelID(aOne);
   // Use MODE_SERVER to force creation of the pipe
   Transport t(id, Transport::MODE_SERVER, nullptr);
   HANDLE serverPipe = t.GetServerPipeHandle();
@@ -34,21 +35,17 @@ CreateTransport(ProcessHandle aProcOne, 
   // NB: we create the server pipe immediately, instead of just
   // grabbing an ID, on purpose.  In the current setup, the client
   // needs to connect to an existing server pipe, so to prevent race
   // conditions, we create the server side here and then dup it to the
   // eventual server process.
   HANDLE serverDup;
   DWORD access = 0;
   DWORD options = DUPLICATE_SAME_ACCESS;
-  if (!DuplicateHandle(GetCurrentProcess(), serverPipe, aProcOne,
-                       &serverDup,
-                       access,
-                       FALSE/*not inheritable*/,
-                       options)) {
+  if (!DuplicateHandle(serverPipe, aProcIdOne, &serverDup, access, options)) {
     return false;
   }
 
   aOne->mPipeName = aTwo->mPipeName = id;
   aOne->mServerPipe = serverDup;
   aTwo->mServerPipe = INVALID_HANDLE_VALUE;
   return true;
 }
--- a/ipc/glue/moz.build
+++ b/ipc/glue/moz.build
@@ -159,14 +159,16 @@ FINAL_LIBRARY = 'xul'
 for var in ('MOZ_CHILD_PROCESS_NAME', 'MOZ_CHILD_PROCESS_BUNDLE',
             'DLL_PREFIX', 'DLL_SUFFIX'):
     DEFINES[var] = '"%s"' % CONFIG[var]
 
 LOCAL_INCLUDES += [
     '/toolkit/crashreporter',
 ]
 
-if CONFIG['OS_ARCH'] == 'WINNT':
+if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
     LOCAL_INCLUDES += [
+        '/security/sandbox/chromium',
+        '/security/sandbox/chromium-shim',
         '/security/sandbox/win/src/sandboxbroker',
     ]
 
 FAIL_ON_WARNINGS = True
--- a/ipc/ipdl/ipdl/lower.py
+++ b/ipc/ipdl/ipdl/lower.py
@@ -392,23 +392,23 @@ def _printErrorMessage(msg):
         ExprCall(ExprVar('NS_ERROR'), args=[ msg ]))
 
 def _protocolErrorBreakpoint(msg):
     if isinstance(msg, str):
         msg = ExprLiteral.String(msg)
     return StmtExpr(ExprCall(ExprVar('mozilla::ipc::ProtocolErrorBreakpoint'),
                              args=[ msg ]))
 
-def _ipcFatalError(name, msg, otherprocess, isparent):
+def _ipcFatalError(name, msg, otherpid, isparent):
     if isinstance(name, str):
         name = ExprLiteral.String(name)
     if isinstance(msg, str):
         msg = ExprLiteral.String(msg)
     return StmtExpr(ExprCall(ExprVar('mozilla::ipc::FatalError'),
-                             args=[ name, msg, otherprocess, isparent ]))
+                             args=[ name, msg, otherpid, isparent ]))
 
 def _printWarningMessage(msg):
     if isinstance(msg, str):
         msg = ExprLiteral.String(msg)
     return StmtExpr(
         ExprCall(ExprVar('NS_WARNING'), args=[ msg ]))
 
 def _fatalError(msg):
@@ -1122,21 +1122,21 @@ class Protocol(ipdl.ast.Protocol):
         return ExprVar('LookupSharedMemory')
 
     def isTrackingSharedMemory(self):
         return ExprVar('IsTrackingSharedMemory')
 
     def destroySharedMemory(self):
         return ExprVar('DestroySharedMemory')
 
-    def otherProcessMethod(self):
-        return ExprVar('OtherProcess')
-
-    def callOtherProcess(self, actorThis=None):
-        fn = self.otherProcessMethod()
+    def otherPidMethod(self):
+        return ExprVar('OtherPid')
+
+    def callOtherPid(self, actorThis=None):
+        fn = self.otherPidMethod()
         if actorThis is not None:
             fn = ExprSelect(actorThis, '->', fn.name)
         return ExprCall(fn)
 
     def getChannelMethod(self):
         return ExprVar('GetIPCChannel')
 
     def callGetChannel(self, actorThis=None):
@@ -1243,19 +1243,19 @@ class Protocol(ipdl.ast.Protocol):
 
     def managerVar(self, thisexpr=None):
         assert thisexpr is not None or not self.decl.type.isToplevel()
         mvar = ExprVar('mManager')
         if thisexpr is not None:
             mvar = ExprSelect(thisexpr, '->', mvar.name)
         return mvar
 
-    def otherProcessVar(self):
+    def otherPidVar(self):
         assert self.decl.type.isToplevel()
-        return ExprVar('mOtherProcess')
+        return ExprVar('mOtherPid')
 
     def managedCxxType(self, actortype, side):
         assert self.decl.type.isManagerOf(actortype)
         return Type(_actorName(actortype.name(), side), ptr=1)
 
     def managedMethod(self, actortype, side):
         assert self.decl.type.isManagerOf(actortype)
         return ExprVar('Managed'+  _actorName(actortype.name(), side))
@@ -1679,18 +1679,18 @@ class _GenerateProtocolCode(ipdl.ast.Vis
         bridgefunc = MethodDefn(MethodDecl(
             'Bridge',
             params=[ Decl(parentHandleType, parentvar.name),
                      Decl(childHandleType, childvar.name) ],
             ret=Type.BOOL))
         bridgefunc.addstmt(StmtReturn(ExprCall(
             ExprVar('mozilla::ipc::Bridge'),
             args=[ _backstagePass(),
-                   p.callGetChannel(parentvar), p.callOtherProcess(parentvar),
-                   p.callGetChannel(childvar), p.callOtherProcess(childvar),
+                   p.callGetChannel(parentvar), p.callOtherPid(parentvar),
+                   p.callGetChannel(childvar), p.callOtherPid(childvar),
                    _protocolId(p.decl.type),
                    ExprVar(_messageStartName(p.decl.type) + 'Child')
                    ])))
         return bridgefunc
 
 
     def genOpenFunc(self, o):
         p = self.protocol
@@ -1700,17 +1700,17 @@ class _GenerateProtocolCode(ipdl.ast.Vis
         openervar = ExprVar('opener')
         openfunc = MethodDefn(MethodDecl(
             'Open',
             params=[ Decl(openertype, openervar.name) ],
             ret=Type.BOOL))
         openfunc.addstmt(StmtReturn(ExprCall(
             ExprVar('mozilla::ipc::Open'),
             args=[ _backstagePass(),
-                   p.callGetChannel(openervar), p.callOtherProcess(openervar),
+                   p.callGetChannel(openervar), p.callOtherPid(openervar),
                    _sideToTransportMode(localside),
                    _protocolId(p.decl.type),
                    ExprVar(_messageStartName(p.decl.type) + 'Child')
                    ])))
         return openfunc
 
 
     def genTransitionFunc(self):
@@ -1877,22 +1877,22 @@ def _generateMessageClass(clsname, msgid
                                        ExprVar(priorityEnum),
                                        compression,
                                        ExprLiteral.String(prettyName) ]) ])
     cls.addstmts([ ctor, Whitespace.NL ])
 
     # generate a logging function
     # 'pfx' will be something like "[FooParent] sent"
     pfxvar = ExprVar('__pfx')
-    otherprocess = ExprVar('__otherProcess')
+    otherpid = ExprVar('__otherPid')
     receiving = ExprVar('__receiving')
     logger = MethodDefn(MethodDecl(
         'Log',
         params=([ Decl(Type('std::string', const=1, ref=1), pfxvar.name),
-                  Decl(Type('base::ProcessHandle'), otherprocess.name),
+                  Decl(Type('base::ProcessId'), otherpid.name),
                   Decl(Type('bool'), receiving.name) ]),
         const=1))
     # TODO/cjones: allow selecting what information is printed to
     # the log
     msgvar = ExprVar('__logmsg')
     logger.addstmt(StmtDecl(Decl(Type('std::string'), msgvar.name)))
 
     def appendToMsg(thing):
@@ -1902,17 +1902,17 @@ def _generateMessageClass(clsname, msgid
         StmtExpr(ExprCall(
             ExprVar('StringAppendF'),
             args=[ ExprAddrOf(msgvar),
                    ExprLiteral.String('[time:%" PRId64 "][%d%s%d]'),
                    ExprCall(ExprVar('PR_Now')),
                    ExprCall(ExprVar('base::GetCurrentProcId')),
                    ExprConditional(receiving, ExprLiteral.String('<-'),
                                    ExprLiteral.String('->')),
-                   otherprocess ])),
+                   otherpid ])),
         appendToMsg(pfxvar),
         appendToMsg(ExprLiteral.String(clsname +'(')),
         Whitespace.NL
     ])
 
     # TODO turn this back on when string stuff is sorted
 
     logger.addstmt(appendToMsg(ExprLiteral.String('[TODO])\\n')))
@@ -2863,17 +2863,17 @@ class _GenerateProtocolActorCode(ipdl.as
 
         for actor in channelOpenedActors:
             # add the Alloc interface for actors created when a
             # new channel is opened
             actortype = _cxxBareType(actor.asType(), actor.side)
             self.cls.addstmt(StmtDecl(MethodDecl(
                 _allocMethod(actor.ptype, actor.side).name,
                 params=[ Decl(Type('Transport', ptr=1), 'aTransport'),
-                         Decl(Type('ProcessId'), 'aOtherProcess') ],
+                         Decl(Type('ProcessId'), 'aOtherPid') ],
                 ret=actortype,
                 virtual=1, pure=1)))
 
         # ActorDestroy() method; default is no-op
         self.cls.addstmts([
             Whitespace.NL,
             MethodDefn(MethodDecl(
                 _destroyMethod().name,
@@ -2924,18 +2924,18 @@ class _GenerateProtocolActorCode(ipdl.as
         ctor = ConstructorDefn(ConstructorDecl(self.clsname))
         if ptype.isToplevel():
             ctor.memberinits = [
                 ExprMemberInit(p.channelVar(), [
                     ExprCall(ExprVar('ALLOW_THIS_IN_INITIALIZER_LIST'),
                              [ ExprVar.THIS ]) ]),
                 ExprMemberInit(p.lastActorIdVar(),
                                [ p.actorIdInit(self.side) ]),
-                ExprMemberInit(p.otherProcessVar(),
-                               [ ExprVar('ipc::kInvalidProcessHandle') ]),
+                ExprMemberInit(p.otherPidVar(),
+                               [ ExprVar('ipc::kInvalidProcessId') ]),
                 ExprMemberInit(p.lastShmemIdVar(),
                                [ p.shmemIdInit(self.side) ]),
                 ExprMemberInit(p.stateVar(),
                                [ p.startState() ])
             ]
             if ptype.isToplevel():
                 ctor.memberinits = [ExprMemberInit(
                     p.openedProtocolInterfaceType(),
@@ -2955,37 +2955,37 @@ class _GenerateProtocolActorCode(ipdl.as
         dtor = DestructorDefn(
             DestructorDecl(self.clsname, virtual=True))
         dtor.addstmt(StmtExpr(ExprCall(ExprVar('MOZ_COUNT_DTOR'),
                                                [ ExprVar(self.clsname) ])))
 
         self.cls.addstmts([ dtor, Whitespace.NL ])
 
         if ptype.isToplevel():
-            # Open(Transport*, ProcessHandle, MessageLoop*, Side)
+            # Open(Transport*, ProcessId, MessageLoop*, Side)
             aTransportVar = ExprVar('aTransport')
             aThreadVar = ExprVar('aThread')
-            processvar = ExprVar('aOtherProcess')
+            otherPidVar = ExprVar('aOtherPid')
             sidevar = ExprVar('aSide')
             openmeth = MethodDefn(
                 MethodDecl(
                     'Open',
                     params=[ Decl(Type('Channel::Transport', ptr=True),
                                       aTransportVar.name),
-                             Decl(Type('ProcessHandle'), processvar.name),
+                             Decl(Type('base::ProcessId'), otherPidVar.name),
                              Param(Type('MessageLoop', ptr=True),
                                    aThreadVar.name,
                                    default=ExprLiteral.NULL),
                              Param(Type('mozilla::ipc::Side'),
                                    sidevar.name,
                                    default=ExprVar('mozilla::ipc::UnknownSide')) ],
                     ret=Type.BOOL))
 
             openmeth.addstmts([
-                StmtExpr(ExprAssn(p.otherProcessVar(), processvar)),
+                StmtExpr(ExprAssn(p.otherPidVar(), otherPidVar)),
                 StmtReturn(ExprCall(ExprSelect(p.channelVar(), '.', 'Open'),
                                     [ aTransportVar, aThreadVar, sidevar ]))
             ])
             self.cls.addstmts([
                 openmeth,
                 Whitespace.NL ])
 
             # Open(MessageChannel *, MessageLoop *, Side)
@@ -3000,17 +3000,17 @@ class _GenerateProtocolActorCode(ipdl.as
                              Param(Type('MessageLoop', ptr=True),
                                    aMessageLoop.name),
                              Param(Type('mozilla::ipc::Side'),
                                    sidevar.name,
                                    default=ExprVar('mozilla::ipc::UnknownSide')) ],
                     ret=Type.BOOL))
 
             openmeth.addstmts([
-                StmtExpr(ExprAssn(p.otherProcessVar(), ExprVar('ipc::kInvalidProcessHandle'))),
+                StmtExpr(ExprAssn(p.otherPidVar(), ExprVar('ipc::kCurrentProcessId'))),
                 StmtReturn(ExprCall(ExprSelect(p.channelVar(), '.', 'Open'),
                                     [ aChannel, aMessageLoop, sidevar ]))
             ])
             self.cls.addstmts([
                 openmeth,
                 Whitespace.NL ])
 
             # Close()
@@ -3326,79 +3326,69 @@ class _GenerateProtocolActorCode(ipdl.as
                     CppDirective('else'),
                     _runtimeAbort('This method is Windows-only'),
                     CppDirective('endif'),
                     ])
 
             self.cls.addstmts([ processnative, Whitespace.NL ])
 
         if ptype.isToplevel() and self.side is 'parent':
-            ## void SetOtherProcess(ProcessHandle pid)
-            otherprocessvar = ExprVar('aOtherProcess')
-            setotherprocess = MethodDefn(MethodDecl(
-                    'SetOtherProcess',
-                    params=[ Decl(Type('ProcessHandle'), otherprocessvar.name)]))
-            setotherprocess.addstmt(StmtExpr(ExprAssn(p.otherProcessVar(), otherprocessvar)))
+            ## void SetOtherProcessId(ProcessId aOtherPid)
+            otherpidvar = ExprVar('aOtherPid')
+            setotherprocessid = MethodDefn(MethodDecl(
+                    'SetOtherProcessId',
+                    params=[ Decl(Type('base::ProcessId'), otherpidvar.name)]))
+            setotherprocessid.addstmts([
+                StmtExpr(ExprAssn(p.otherPidVar(), otherpidvar)),
+            ])
             self.cls.addstmts([
-                    setotherprocess,
+                    setotherprocessid,
                     Whitespace.NL])
 
             ## bool GetMinidump(nsIFile** dump)
             self.cls.addstmt(Label.PROTECTED)
 
-            otherpidvar = ExprVar('OtherSidePID')
-            otherpid = MethodDefn(MethodDecl(
-                otherpidvar.name, params=[ ],
-                ret=Type('base::ProcessId'),
-                const=1))
-            otherpid.addstmts([
-                StmtReturn(ExprCall(
-                    ExprVar('base::GetProcId'),
-                    args=[ p.otherProcessVar() ])),
-            ])
-
             dumpvar = ExprVar('aDump')
             seqvar = ExprVar('aSequence')
             getdump = MethodDefn(MethodDecl(
                 'TakeMinidump',
                 params=[ Decl(Type('nsIFile', ptrptr=1), dumpvar.name),
                          Decl(Type.UINT32PTR, seqvar.name)],
                 ret=Type.BOOL,
                 const=1))
             getdump.addstmts([
                 CppDirective('ifdef', 'MOZ_CRASHREPORTER'),
                 StmtReturn(ExprCall(
                     ExprVar('XRE_TakeMinidumpForChild'),
-                    args=[ ExprCall(otherpidvar), dumpvar, seqvar ])),
+                    args=[ ExprCall(p.otherPidMethod()), dumpvar, seqvar ])),
                 CppDirective('else'),
                 StmtReturn.FALSE,
                 CppDirective('endif')
             ])
-            self.cls.addstmts([ otherpid, Whitespace.NL,
-                                getdump, Whitespace.NL ])
+            self.cls.addstmts([ getdump, Whitespace.NL ])
 
         ## private methods
         self.cls.addstmt(Label.PRIVATE)
 
         ## FatalError()
         msgparam = ExprVar('aMsg')
         msgvar = ExprVar('formattedMessage')
         actorname = _actorName(p.name, self.side)
         fatalerror = MethodDefn(MethodDecl(
             'FatalError',
             params=[ Decl(Type('char', const=1, ptrconst=1), msgparam.name) ],
             const=1, never_inline=1))
         if self.side is 'parent':
-            otherprocess = p.callOtherProcess()
+            otherpid = p.callOtherPid()
             isparent = ExprLiteral.TRUE
         else:
-            otherprocess = ExprLiteral.ZERO
+            otherpid = ExprLiteral.ZERO
             isparent = ExprLiteral.FALSE
         fatalerror.addstmts([
-            _ipcFatalError(actorname, msgparam, otherprocess, isparent)
+            _ipcFatalError(actorname, msgparam, otherpid, isparent)
         ])
         self.cls.addstmts([ fatalerror, Whitespace.NL ])
 
         ## DestroySubtree(bool normal)
         whyvar = ExprVar('why')
         subtreewhyvar = ExprVar('subtreewhy')
         kidsvar = ExprVar('kids')
         ivar = ExprVar('i')
@@ -3530,18 +3520,18 @@ class _GenerateProtocolActorCode(ipdl.as
 
         ## private members
         self.cls.addstmt(StmtDecl(Decl(p.channelType(), 'mChannel')))
         if ptype.isToplevel():
             self.cls.addstmts([
                 StmtDecl(Decl(Type('IDMap', T=Type('ProtocolBase')),
                               p.actorMapVar().name)),
                 StmtDecl(Decl(_actorIdType(), p.lastActorIdVar().name)),
-                StmtDecl(Decl(Type('ProcessHandle'),
-                              p.otherProcessVar().name))
+                StmtDecl(Decl(Type('base::ProcessId'),
+                              p.otherPidVar().name))
             ])
         elif ptype.isManaged():
             self.cls.addstmts([
                 StmtDecl(Decl(p.managerInterfaceType(ptr=1),
                               p.managerVar().name)),
                 StmtDecl(Decl(_actorIdType(), p.idVar().name))
             ])
         if p.decl.type.isToplevel():
@@ -3620,21 +3610,22 @@ class _GenerateProtocolActorCode(ipdl.as
             params=[ Decl(_shmemType(ref=1), shmemvar.name) ],
             virtual=1))
         istracking = MethodDefn(MethodDecl(
             p.isTrackingSharedMemory().name,
             ret=Type.BOOL,
             params=[ Decl(_rawShmemType(ptr=1), rawvar.name) ],
             virtual=1))
 
-        otherprocess = MethodDefn(MethodDecl(
-            p.otherProcessMethod().name,
-            ret=Type('ProcessHandle'),
+        otherpid = MethodDefn(MethodDecl(
+            p.otherPidMethod().name,
+            ret=Type('base::ProcessId'),
             const=1,
             virtual=1))
+
         getchannel = MethodDefn(MethodDecl(
             p.getChannelMethod().name,
             ret=Type('MessageChannel', ptr=1),
             virtual=1))
 
         clonemanagees = MethodDefn(MethodDecl(
             p.cloneManagees().name,
             params=[ Decl(protocolbase, sourcevar.name),
@@ -3696,17 +3687,17 @@ class _GenerateProtocolActorCode(ipdl.as
             createshmem.addstmts([
                 StmtDecl(
                     Decl(_shmemType(), shmemvar.name),
                     initargs=[ _shmemBackstagePass(),
                                _refptrGet(rawvar),
                                p.nextShmemIdExpr(self.side) ]),
                 StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name),
                          init=_shmemShareTo(shmemvar,
-                                            p.callOtherProcess(),
+                                            p.callOtherPid(),
                                             p.routingId()))
             ])
             failif = StmtIf(ExprNot(descriptorvar))
             failif.addifstmt(StmtReturn(ExprLiteral.NULL))
             createshmem.addstmt(failif)
 
             failif = StmtIf(ExprNot(ExprCall(
                 ExprSelect(p.channelVar(), p.channelSel(), 'Send'),
@@ -3740,17 +3731,17 @@ class _GenerateProtocolActorCode(ipdl.as
             adoptshmem.addstmts([
                 StmtDecl(
                     Decl(_shmemType(), shmemvar.name),
                     initargs=[ _shmemBackstagePass(),
                                rawvar,
                                p.nextShmemIdExpr(self.side) ]),
                 StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name),
                          init=_shmemShareTo(shmemvar,
-                                            p.callOtherProcess(),
+                                            p.callOtherPid(),
                                             p.routingId()))
             ])
             failif = StmtIf(ExprNot(descriptorvar))
             failif.addifstmt(StmtReturn.FALSE)
             adoptshmem.addstmt(failif)
 
             failif = StmtIf(ExprNot(ExprCall(
                 ExprSelect(p.channelVar(), p.channelSel(), 'Send'),
@@ -3804,17 +3795,17 @@ class _GenerateProtocolActorCode(ipdl.as
                     StmtExpr(ExprDelete(descriptorvar)),
                     StmtReturn.TRUE])
             destroyshmem.addstmts([
                 failif,
                 Whitespace.NL,
                 StmtDecl(Decl(Type('Message', ptr=1), descriptorvar.name),
                          init=_shmemUnshareFrom(
                              shmemvar,
-                             p.callOtherProcess(),
+                             p.callOtherPid(),
                              p.routingId())),
                 Whitespace.NL,
                 StmtExpr(p.removeShmemId(idvar)),
                 StmtExpr(_shmemDealloc(rawvar)),
                 Whitespace.NL,
                 returnif,
                 Whitespace.NL,
                 StmtReturn(ExprBinary(
@@ -3840,17 +3831,17 @@ class _GenerateProtocolActorCode(ipdl.as
                     _runtimeAbort('this protocol tree does not use shmem'),
                     StmtReturn(_Result.NotKnown)
                 ])
                 self.asyncSwitch.addcase(
                     CaseLabel('SHMEM_CREATED_MESSAGE_TYPE'), abort)
                 self.asyncSwitch.addcase(
                     CaseLabel('SHMEM_DESTROYED_MESSAGE_TYPE'), abort)
 
-            otherprocess.addstmt(StmtReturn(p.otherProcessVar()))
+            otherpid.addstmt(StmtReturn(p.otherPidVar()))
             getchannel.addstmt(StmtReturn(ExprAddrOf(p.channelVar())))
         else:
             # delegate registration to manager
             register.addstmt(StmtReturn(ExprCall(
                 ExprSelect(p.managerVar(), '->', p.registerMethod().name),
                 [ routedvar ])))
             registerid.addstmt(StmtReturn(ExprCall(
                 ExprSelect(p.managerVar(), '->', p.registerIDMethod().name),
@@ -3872,18 +3863,18 @@ class _GenerateProtocolActorCode(ipdl.as
                 [ idvar ])))
             istracking.addstmt(StmtReturn(ExprCall(
                 ExprSelect(p.managerVar(), '->',
                            p.isTrackingSharedMemory().name),
                 [ rawvar ])))
             destroyshmem.addstmt(StmtReturn(ExprCall(
                 ExprSelect(p.managerVar(), '->', p.destroySharedMemory().name),
                 [ shmemvar ])))
-            otherprocess.addstmt(StmtReturn(
-                p.callOtherProcess(p.managerVar())))
+            otherpid.addstmt(StmtReturn(
+                p.callOtherPid(p.managerVar())))
             getchannel.addstmt(StmtReturn(p.channelVar()))
 
         cloneprotocol.addstmts([
             _runtimeAbort('Clone() for ' +
                           p.name +
                           ' has not yet been implemented'),
             StmtReturn(ExprLiteral.NULL)
         ])
@@ -4019,17 +4010,17 @@ class _GenerateProtocolActorCode(ipdl.as
                  lookup,
                  unregister,
                  removemanagee,
                  createshmem,
                  adoptshmem,
                  lookupshmem,
                  istracking,
                  destroyshmem,
-                 otherprocess,
+                 otherpid,
                  getchannel,
                  clonemanagees,
                  cloneprotocol,
                  Whitespace.NL ]
 
     def makeShmemIface(self):
         p = self.protocol
         idvar = ExprVar('id')
@@ -4622,17 +4613,17 @@ class _GenerateProtocolActorCode(ipdl.as
         def _fdBackstagePass():
             return ExprCall(ExprVar('FileDescriptor::IPDLPrivate'))
 
         write = MethodDefn(self.writeMethodDecl(intype, var))
         write.addstmts([
             StmtDecl(Decl(_fdPickleType(), picklevar.name),
                      init=ExprCall(ExprSelect(var, '.', 'ShareTo'),
                                    args=[ _fdBackstagePass(),
-                                          self.protocol.callOtherProcess() ])),
+                                          self.protocol.callOtherPid() ])),
             StmtExpr(ExprCall(ExprVar('IPC::WriteParam'),
                               args=[ msgvar, picklevar ])),
         ])
 
         read = MethodDefn(self.readMethodDecl(outtype, var))
         ifread = StmtIf(ExprNot(ExprCall(ExprVar('IPC::ReadParam'),
                                          args=[ msgvar, itervar,
                                                 ExprAddrOf(picklevar) ])))
@@ -5399,17 +5390,17 @@ class _GenerateProtocolActorCode(ipdl.as
 
     def logMessage(self, md, msgptr, pfx, actor=None, receiving=False):
         actorname = _actorName(self.protocol.name, self.side)
 
         topLevel = self.protocol.decl.type.toplevel().name()
         return _ifLogging(ExprLiteral.String(topLevel), [ StmtExpr(ExprCall(
             ExprSelect(msgptr, '->', 'Log'),
             args=[ ExprLiteral.String('['+ actorname +'] '+ pfx),
-                   self.protocol.callOtherProcess(actor),
+                   self.protocol.callOtherPid(actor),
                    ExprLiteral.TRUE if receiving else ExprLiteral.FALSE ])) ])
 
     def profilerLabel(self, tag, msgname):
         return StmtExpr(ExprCall(ExprVar('PROFILER_LABEL'),
                                  [ ExprLiteral.String('IPDL::' + self.protocol.name),
                                    ExprLiteral.String(tag + msgname),
                                    ExprVar('js::ProfileEntry::Category::OTHER') ]))
 
--- a/ipc/ipdl/test/cxx/IPDLUnitTestProcessChild.cpp
+++ b/ipc/ipdl/test/cxx/IPDLUnitTestProcessChild.cpp
@@ -14,17 +14,17 @@ using mozilla::ipc::IOThreadChild;
 
 namespace mozilla {
 namespace _ipdltest {
 
 bool
 IPDLUnitTestProcessChild::Init()
 {
     IPDLUnitTestChildInit(IOThreadChild::channel(),
-                          ParentHandle(),
+                          ParentId(),
                           IOThreadChild::message_loop());
 
     if (NS_FAILED(nsRegion::InitStatic()))
       return false;
 
     return true;
 }
 
--- a/ipc/ipdl/test/cxx/IPDLUnitTestProcessChild.h
+++ b/ipc/ipdl/test/cxx/IPDLUnitTestProcessChild.h
@@ -11,18 +11,18 @@
 namespace mozilla {
 namespace _ipdltest {
 
 class IPDLUnitTestProcessChild : public mozilla::ipc::ProcessChild
 {
   typedef mozilla::ipc::ProcessChild ProcessChild;
 
 public:
-  IPDLUnitTestProcessChild(ProcessHandle aParentHandle) :
-    ProcessChild(aParentHandle)
+  IPDLUnitTestProcessChild(ProcessId aParentPid) :
+    ProcessChild(aParentPid)
   { }
 
   ~IPDLUnitTestProcessChild()
   { }
 
   virtual bool Init();
 };
 
--- a/ipc/ipdl/test/cxx/IPDLUnitTests.h
+++ b/ipc/ipdl/test/cxx/IPDLUnitTests.h
@@ -76,17 +76,17 @@ void IPDLUnitTestMain(void* aData);
 void QuitParent();
 
 //-----------------------------------------------------------------------------
 // child process only
 
 extern void* gChildActor;
 
 void IPDLUnitTestChildInit(IPC::Channel* transport,
-                           base::ProcessHandle parent,
+                           base::ProcessId parentPid,
                            MessageLoop* worker);
 
 void QuitChild();
 
 } // namespace _ipdltest
 } // namespace mozilla
 
 
--- a/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp
+++ b/ipc/ipdl/test/cxx/IPDLUnitTests.template.cpp
@@ -366,17 +366,17 @@ DeleteChildActor()
 ${CHILD_DELETE_CASES}
 //-----------------------------------------------------------------------------
     default:  ::mozilla::_ipdltest::fail("???");
     }
 }
 
 void
 IPDLUnitTestChildInit(IPC::Channel* transport,
-                      base::ProcessHandle parent,
+                      base::ProcessId parentPid,
                       MessageLoop* worker)
 {
     switch (IPDLUnitTest()) {
 //-----------------------------------------------------------------------------
 //===== TEMPLATED =====
 ${CHILD_INIT_CASES}
 //-----------------------------------------------------------------------------
 
--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
+++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
@@ -127,16 +127,30 @@ SandboxBroker::SetSecurityLevelForConten
   // Add the policy for the client side of a pipe. It is just a file
   // in the \pipe\ namespace. We restrict it to pipes that start with
   // "chrome." so the sandboxed process cannot connect to system services.
   result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
                             sandbox::TargetPolicy::FILES_ALLOW_ANY,
                             L"\\??\\pipe\\chrome.*");
   ret = ret && (sandbox::SBOX_ALL_OK == result);
 
+  // The content process needs to be able to duplicate named pipes back to the
+  // broker process, which are File type handles.
+  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
+                            sandbox::TargetPolicy::HANDLES_DUP_BROKER,
+                            L"File");
+  ret = ret && (sandbox::SBOX_ALL_OK == result);
+
+  // The content process needs to be able to duplicate shared memory to the
+  // broker process, which are Section type handles.
+  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
+                            sandbox::TargetPolicy::HANDLES_DUP_BROKER,
+                            L"Section");
+  ret = ret && (sandbox::SBOX_ALL_OK == result);
+
   return ret;
 }
 #endif
 
 bool
 SandboxBroker::SetSecurityLevelForPluginProcess(int32_t aSandboxLevel)
 {
   if (!mPolicy) {
@@ -199,16 +213,23 @@ SandboxBroker::SetSecurityLevelForPlugin
   // Add the policy for the client side of a pipe. It is just a file
   // in the \pipe\ namespace. We restrict it to pipes that start with
   // "chrome." so the sandboxed process cannot connect to system services.
   result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
                             sandbox::TargetPolicy::FILES_ALLOW_ANY,
                             L"\\??\\pipe\\chrome.*");
   ret = ret && (sandbox::SBOX_ALL_OK == result);
 
+  // The NPAPI process needs to be able to duplicate shared memory to the
+  // content process, which are Section type handles.
+  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
+                            sandbox::TargetPolicy::HANDLES_DUP_ANY,
+                            L"Section");
+  ret = ret && (sandbox::SBOX_ALL_OK == result);
+
   return ret;
 }
 
 bool
 SandboxBroker::SetSecurityLevelForIPDLUnitTestProcess()
 {
   if (!mPolicy) {
     return false;
--- a/toolkit/xre/nsEmbedFunctions.cpp
+++ b/toolkit/xre/nsEmbedFunctions.cpp
@@ -456,24 +456,16 @@ XRE_InitChildProcess(int aArgc,
   const char* const parentPIDString = aArgv[aArgc-1];
   MOZ_ASSERT(parentPIDString, "NULL parent PID");
   --aArgc;
 
   char* end = 0;
   base::ProcessId parentPID = strtol(parentPIDString, &end, 10);
   MOZ_ASSERT(!*end, "invalid parent PID");
 
-  // Retrieve the parent process handle. We need this for shared memory use and
-  // for creating new transports in the child.
-  base::ProcessHandle parentHandle = 0;
-  if (XRE_GetProcessType() != GeckoProcessType_GMPlugin) {
-    mozilla::DebugOnly<bool> ok = base::OpenProcessHandle(parentPID, &parentHandle);
-    MOZ_ASSERT(ok, "can't open handle to parent");
-  }
-
 #if defined(XP_WIN)
   // On Win7+, register the application user model id passed in by
   // parent. This insures windows created by the container properly
   // group with the parent app on the Win7 taskbar.
   const char* const appModelUserId = aArgv[--aArgc];
   if (appModelUserId) {
     // '-' implies no support
     if (*appModelUserId != '-') {
@@ -529,43 +521,43 @@ XRE_InitChildProcess(int aArgc,
 #endif
 
       switch (XRE_GetProcessType()) {
       case GeckoProcessType_Default:
         NS_RUNTIMEABORT("This makes no sense");
         break;
 
       case GeckoProcessType_Plugin:
-        process = new PluginProcessChild(parentHandle);
+        process = new PluginProcessChild(parentPID);
         break;
 
       case GeckoProcessType_Content: {
-          process = new ContentProcess(parentHandle);
+          process = new ContentProcess(parentPID);
           // If passed in grab the application path for xpcom init
           nsCString appDir;
           for (int idx = aArgc; idx > 0; idx--) {
             if (aArgv[idx] && !strcmp(aArgv[idx], "-appdir")) {
               appDir.Assign(nsDependentCString(aArgv[idx+1]));
               static_cast<ContentProcess*>(process.get())->SetAppDir(appDir);
               break;
             }
           }
         }
         break;
 
       case GeckoProcessType_IPDLUnitTest:
 #ifdef MOZ_IPDL_TESTS
-        process = new IPDLUnitTestProcessChild(parentHandle);
+        process = new IPDLUnitTestProcessChild(parentPID);
 #else 
         NS_RUNTIMEABORT("rebuild with --enable-ipdl-tests");
 #endif
         break;
 
       case GeckoProcessType_GMPlugin:
-        process = new gmp::GMPProcessChild(parentHandle);
+        process = new gmp::GMPProcessChild(parentPID);
         break;
 
       default:
         NS_RUNTIMEABORT("Unknown main thread class");
       }
 
       if (!process->Init()) {
         profiler_shutdown();
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1142,16 +1142,19 @@ void nsBaseWidget::CreateCompositor(int 
   CreateCompositorVsyncDispatcher();
   mCompositorParent = NewCompositorParent(aWidth, aHeight);
   MessageChannel *parentChannel = mCompositorParent->GetIPCChannel();
   nsRefPtr<ClientLayerManager> lm = new ClientLayerManager(this);
   MessageLoop *childMessageLoop = CompositorParent::CompositorLoop();
   mCompositorChild = new CompositorChild(lm);
   mCompositorChild->Open(parentChannel, childMessageLoop, ipc::ChildSide);
 
+  // Make sure the parent knows it is same process.
+  mCompositorParent->SetOtherProcessId(kCurrentProcessId);
+
   if (gfxPrefs::AsyncPanZoomEnabled() &&
       (WindowType() == eWindowType_toplevel || WindowType() == eWindowType_child)) {
     ConfigureAPZCTreeManager();
   }
 
   TextureFactoryIdentifier textureFactoryIdentifier;
   PLayerTransactionChild* shadowManager = nullptr;
   nsTArray<LayersBackend> backendHints;