Bug 1268559 - Go back to ContentParent controlling process shutdown (i.e., backout bug 1262898) (r=dvander)
authorBill McCloskey <billm@mozilla.com>
Fri, 27 May 2016 18:03:12 -0700
changeset 332584 a736ae904fda23a207e2a67219e0f4742178263c
parent 332583 7f153687ee15abb29c8c19399ea9ebf70f3ac565
child 332585 29be71153eccaaaf4ae3f87306c6478a84354289
push idunknown
push userunknown
push dateunknown
reviewersdvander
bugs1268559, 1262898
milestone50.0a1
Bug 1268559 - Go back to ContentParent controlling process shutdown (i.e., backout bug 1262898) (r=dvander)
dom/ipc/ContentParent.cpp
gfx/ipc/GPUProcessHost.cpp
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
ipc/chromium/src/chrome/common/process_watcher_win.cc
ipc/glue/GeckoChildProcessHost.cpp
ipc/glue/GeckoChildProcessHost.h
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1986,16 +1986,23 @@ ContentParent::RecvDeallocateLayerTreeId
     // You can't deallocate layer tree ids that you didn't allocate
     KillHard("DeallocateLayerTreeId");
   }
   return true;
 }
 
 namespace {
 
+void
+DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
+{
+  RefPtr<DeleteTask<GeckoChildProcessHost>> task = new DeleteTask<GeckoChildProcessHost>(aSubprocess);
+  XRE_GetIOMessageLoop()->PostTask(task.forget());
+}
+
 // This runnable only exists to delegate ownership of the
 // ContentParent to this runnable, until it's deleted by the event
 // system.
 struct DelayedDeleteContentParentTask : public Runnable
 {
   explicit DelayedDeleteContentParentTask(ContentParent* aObj) : mObj(aObj) { }
 
   // No-op
@@ -2117,20 +2124,19 @@ ContentParent::ActorDestroy(ActorDestroy
   MOZ_ASSERT(idleService);
   RefPtr<ParentIdleListener> listener;
   for (int32_t i = mIdleListeners.Length() - 1; i >= 0; --i) {
     listener = static_cast<ParentIdleListener*>(mIdleListeners[i].get());
     idleService->RemoveIdleObserver(listener, listener->mTime);
   }
   mIdleListeners.Clear();
 
-  if (mSubprocess) {
-    mSubprocess->DissociateActor();
-    mSubprocess = nullptr;
-  }
+  MessageLoop::current()->
+    PostTask(NewRunnableFunction(DelayedDeleteSubprocess, mSubprocess));
+  mSubprocess = nullptr;
 
   // IPDL rules require actors to live on past ActorDestroy, but it
   // may be that the kungFuDeathGrip above is the last reference to
   // |this|.  If so, when we go out of scope here, we're deleted and
   // all hell breaks loose.
   //
   // This runnable ensures that a reference to |this| lives on at
   // least until after the current task finishes running.
@@ -3316,31 +3322,31 @@ ContentParent::DeallocPAPZParent(PAPZPar
   return true;
 }
 
 PCompositorBridgeParent*
 ContentParent::AllocPCompositorBridgeParent(mozilla::ipc::Transport* aTransport,
                                             base::ProcessId aOtherProcess)
 {
   return GPUProcessManager::Get()->CreateTabCompositorBridge(
-    aTransport, aOtherProcess, mSubprocess);
+    aTransport, aOtherProcess);
 }
 
 gfx::PVRManagerParent*
 ContentParent::AllocPVRManagerParent(Transport* aTransport,
                                      ProcessId aOtherProcess)
 {
   return gfx::VRManagerParent::CreateCrossProcess(aTransport, aOtherProcess);
 }
 
 PImageBridgeParent*
 ContentParent::AllocPImageBridgeParent(mozilla::ipc::Transport* aTransport,
                                        base::ProcessId aOtherProcess)
 {
-  return ImageBridgeParent::Create(aTransport, aOtherProcess, mSubprocess);
+  return ImageBridgeParent::Create(aTransport, aOtherProcess);
 }
 
 PBackgroundParent*
 ContentParent::AllocPBackgroundParent(Transport* aTransport,
                                       ProcessId aOtherProcess)
 {
   return BackgroundParent::Alloc(this, aTransport, aOtherProcess);
 }
--- a/gfx/ipc/GPUProcessHost.cpp
+++ b/gfx/ipc/GPUProcessHost.cpp
@@ -187,23 +187,31 @@ GPUProcessHost::KillHard(const char* aRe
     NS_WARNING("failed to kill subprocess!");
   }
 
   SetAlreadyDead();
   XRE_GetIOMessageLoop()->PostTask(
     NewRunnableFunction(&ProcessWatcher::EnsureProcessTerminated, handle, /*force=*/true));
 }
 
+static void
+DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
+{
+  XRE_GetIOMessageLoop()->
+    PostTask(mozilla::MakeAndAddRef<DeleteTask<GeckoChildProcessHost>>(aSubprocess));
+}
+
 void
 GPUProcessHost::DestroyProcess()
 {
   // Cancel all tasks. We don't want anything triggering after our caller
   // expects this to go away.
   {
     MonitorAutoLock lock(mMonitor);
     mTaskFactory.RevokeAll();
   }
 
-  DissociateActor();
+  MessageLoop::current()->
+    PostTask(NewRunnableFunction(DelayedDeleteSubprocess, this));
 }
 
 } // namespace gfx
 } // namespace mozilla
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -165,20 +165,19 @@ GPUProcessManager::CreateTopLevelComposi
     aUseAPZ,
     aUseExternalSurfaceSize,
     aSurfaceWidth,
     aSurfaceHeight);
 }
 
 PCompositorBridgeParent*
 GPUProcessManager::CreateTabCompositorBridge(ipc::Transport* aTransport,
-                                             base::ProcessId aOtherProcess,
-                                             ipc::GeckoChildProcessHost* aSubprocess)
+                                             base::ProcessId aOtherProcess)
 {
-  return CompositorBridgeParent::Create(aTransport, aOtherProcess, aSubprocess);
+  return CompositorBridgeParent::Create(aTransport, aOtherProcess);
 }
 
 already_AddRefed<APZCTreeManager>
 GPUProcessManager::GetAPZCTreeManagerForLayers(uint64_t aLayersId)
 {
   return CompositorBridgeParent::GetAPZCTreeManager(aLayersId);
 }
 
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -65,18 +65,17 @@ public:
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     int aSurfaceWidth,
     int aSurfaceHeight);
 
   layers::PCompositorBridgeParent* CreateTabCompositorBridge(
     ipc::Transport* aTransport,
-    base::ProcessId aOtherProcess,
-    ipc::GeckoChildProcessHost* aSubprocess);
+    base::ProcessId aOtherProcess);
 
   // This returns a reference to the APZCTreeManager to which
   // pan/zoom-related events can be sent.
   already_AddRefed<APZCTreeManager> GetAPZCTreeManagerForLayers(uint64_t aLayersId);
 
   // Allocate an ID that can be used to refer to a layer tree and
   // associated resources that live only on the compositor thread.
   //
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -63,17 +63,16 @@
 #include "nsXULAppAPI.h"                // for XRE_GetIOMessageLoop
 #include "nsIXULRuntime.h"              // for BrowserTabsRemoteAutostart
 #ifdef XP_WIN
 #include "mozilla/layers/CompositorD3D11.h"
 #include "mozilla/layers/CompositorD3D9.h"
 #endif
 #include "GeckoProfiler.h"
 #include "mozilla/ipc/ProtocolTypes.h"
-#include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/unused.h"
 #include "mozilla/Hal.h"
 #include "mozilla/HalTypes.h"
 #include "mozilla/StaticPtr.h"
 #ifdef MOZ_ENABLE_PROFILER_SPS
 #include "ProfilerMarkers.h"
 #endif
 #include "mozilla/VsyncDispatcher.h"
@@ -1814,17 +1813,16 @@ class CrossProcessCompositorBridgeParent
                                                  public ShmemAllocator
 {
   friend class CompositorBridgeParent;
 
 public:
   explicit CrossProcessCompositorBridgeParent(Transport* aTransport)
     : CompositorBridgeParentIPCAllocator("CrossProcessCompositorBridgeParent")
     , mTransport(aTransport)
-    , mSubprocess(nullptr)
     , mNotifyAfterRemotePaint(false)
     , mDestroyCalled(false)
   {
     MOZ_ASSERT(NS_IsMainThread());
     // Always run destructor on the main thread
     SetMessageLoopToPostDestructionTo(MessageLoop::current());
   }
 
@@ -1993,17 +1991,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().
   RefPtr<CrossProcessCompositorBridgeParent> mSelfRef;
   Transport* mTransport;
-  ipc::GeckoChildProcessHost* mSubprocess;
 
   RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
   // If true, we should send a RemotePaintIsReady message when the layer transaction
   // is received
   bool mNotifyAfterRemotePaint;
   bool mDestroyCalled;
 };
 
@@ -2153,28 +2150,23 @@ OpenCompositor(CrossProcessCompositorBri
                Transport* aTransport, ProcessId aOtherPid,
                MessageLoop* aIOLoop)
 {
   DebugOnly<bool> ok = aCompositor->Open(aTransport, aOtherPid, aIOLoop);
   MOZ_ASSERT(ok);
 }
 
 /*static*/ PCompositorBridgeParent*
-CompositorBridgeParent::Create(Transport* aTransport, ProcessId aOtherPid, GeckoChildProcessHost* aProcessHost)
+CompositorBridgeParent::Create(Transport* aTransport, ProcessId aOtherPid)
 {
   gfxPlatform::InitLayersIPC();
 
   RefPtr<CrossProcessCompositorBridgeParent> cpcp =
     new CrossProcessCompositorBridgeParent(aTransport);
 
-  if (aProcessHost) {
-    cpcp->mSubprocess = aProcessHost;
-    aProcessHost->AssociateActor();
-  }
-
   cpcp->mSelfRef = cpcp;
   CompositorLoop()->PostTask(
     NewRunnableFunction(OpenCompositor, cpcp.get(),
                         aTransport, aOtherPid, XRE_GetIOMessageLoop()));
   // The return value is just compared to null for success checking,
   // we're not sharing a ref.
   return cpcp.get();
 }
@@ -2272,21 +2264,16 @@ CrossProcessCompositorBridgeParent::Recv
 }
 
 void
 CrossProcessCompositorBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   RefPtr<CompositorLRU> lru = CompositorLRU::GetSingleton();
   lru->Remove(this);
 
-  if (mSubprocess) {
-    mSubprocess->DissociateActor();
-    mSubprocess = nullptr;
-  }
-
   // We must keep this object alive untill the code handling message
   // reception is finished on this thread.
   MessageLoop::current()->PostTask(NewRunnableMethod(this, &CrossProcessCompositorBridgeParent::DeferredDestroy));
 }
 
 PLayerTransactionParent*
 CrossProcessCompositorBridgeParent::AllocPLayerTransactionParent(
   const nsTArray<LayersBackend>&,
@@ -2753,17 +2740,17 @@ CrossProcessCompositorBridgeParent::Clon
   base::ProcessHandle aPeerProcess,
   mozilla::ipc::ProtocolCloneContext* aCtx)
 {
   for (unsigned int i = 0; i < aFds.Length(); i++) {
     if (aFds[i].protocolId() == (unsigned)GetProtocolId()) {
       Transport* transport = OpenDescriptor(aFds[i].fd(),
                                             Transport::MODE_SERVER);
       PCompositorBridgeParent* compositor =
-        CompositorBridgeParent::Create(transport, base::GetProcId(aPeerProcess), mSubprocess);
+        CompositorBridgeParent::Create(transport, base::GetProcId(aPeerProcess));
       compositor->CloneManagees(this, aCtx);
       compositor->IToplevelProtocol::SetTransport(transport);
       // The reference to the compositor thread is held in OnChannelConnected().
       // We need to do this for cloned actors, too.
       compositor->OnChannelConnected(base::GetProcId(aPeerProcess));
       return compositor;
     }
   }
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -46,17 +46,16 @@ namespace mozilla {
 class CancelableRunnable;
 
 namespace gfx {
 class DrawTarget;
 class GPUProcessManager;
 } // namespace gfx
 
 namespace ipc {
-class GeckoChildProcessHost;
 class Shmem;
 } // namespace ipc
 
 namespace layers {
 
 class APZCTreeManager;
 class AsyncCompositionManager;
 class Compositor;
@@ -395,17 +394,17 @@ public:
   static void SetControllerForLayerTree(uint64_t aLayersId,
                                         GeckoContentController* aController);
 
   /**
    * A new child process has been configured to push transactions
    * directly to us.  Transport is to its thread context.
    */
   static PCompositorBridgeParent*
-  Create(Transport* aTransport, ProcessId aOtherProcess, mozilla::ipc::GeckoChildProcessHost* aProcessHost);
+  Create(Transport* aTransport, ProcessId aOtherProcess);
 
   struct LayerTreeState {
     LayerTreeState();
     ~LayerTreeState();
     RefPtr<Layer> mRoot;
     RefPtr<GeckoContentController> mController;
     CompositorBridgeParent* mParent;
     LayerManagerComposite* mLayerManager;
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -11,17 +11,16 @@
 #include "base/process.h"               // for ProcessId
 #include "base/task.h"                  // for CancelableTask, DeleteTask, etc
 #include "mozilla/gfx/Point.h"                   // for IntSize
 #include "mozilla/Hal.h"                // for hal::SetCurrentThreadPriority()
 #include "mozilla/HalTypes.h"           // for hal::THREAD_PRIORITY_COMPOSITOR
 #include "mozilla/ipc/MessageChannel.h" // for MessageChannel, etc
 #include "mozilla/ipc/ProtocolUtils.h"
 #include "mozilla/ipc/Transport.h"      // for Transport
-#include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/media/MediaSystemResourceManagerParent.h" // for MediaSystemResourceManagerParent
 #include "mozilla/layers/CompositableTransactionParent.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/LayersMessages.h"  // for EditReply
 #include "mozilla/layers/LayersSurfaces.h"  // for PGrallocBufferParent
 #include "mozilla/layers/PCompositableParent.h"
 #include "mozilla/layers/PImageBridgeParent.h"
 #include "mozilla/layers/TextureHostOGL.h"  // for TextureHostOGL
@@ -53,17 +52,16 @@ CompositorThreadHolder* GetCompositorThr
 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
                                      Transport* aTransport,
                                      ProcessId aChildProcessId)
   : CompositableParentManager("ImageBridgeParent")
   , mMessageLoop(aLoop)
   , mTransport(aTransport)
   , mSetChildThreadPriority(false)
   , mClosed(false)
-  , mSubprocess(nullptr)
 {
   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
@@ -95,21 +93,16 @@ ImageBridgeParent::~ImageBridgeParent()
 }
 
 void
 ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
 {
   // Can't alloc/dealloc shmems from now on.
   mClosed = true;
 
-  if (mSubprocess) {
-    mSubprocess->DissociateActor();
-    mSubprocess = nullptr;
-  }
-
   MessageLoop::current()->PostTask(NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy));
 
   // It is very important that this method gets called at shutdown (be it a clean
   // or an abnormal shutdown), because DeferredDestroy is what clears mSelfRef.
   // If mSelfRef is not null and ActorDestroy is not called, the ImageBridgeParent
   // is leaked which causes the CompositorThreadHolder to be leaked and
   // CompsoitorParent's shutdown ends up spinning the event loop forever, waiting
   // for the compositor thread to terminate.
@@ -198,26 +191,21 @@ static void
 ConnectImageBridgeInParentProcess(ImageBridgeParent* aBridge,
                                   Transport* aTransport,
                                   base::ProcessId aOtherPid)
 {
   aBridge->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ParentSide);
 }
 
 /*static*/ PImageBridgeParent*
-ImageBridgeParent::Create(Transport* aTransport, ProcessId aChildProcessId, GeckoChildProcessHost* aProcessHost)
+ImageBridgeParent::Create(Transport* aTransport, ProcessId aChildProcessId)
 {
   MessageLoop* loop = CompositorThreadHolder::Loop();
   RefPtr<ImageBridgeParent> bridge = new ImageBridgeParent(loop, aTransport, aChildProcessId);
 
-  if (aProcessHost) {
-    bridge->mSubprocess = aProcessHost;
-    aProcessHost->AssociateActor();
-  }
-
   loop->PostTask(NewRunnableFunction(ConnectImageBridgeInParentProcess,
                                      bridge.get(), aTransport, aChildProcessId));
   return bridge.get();
 }
 
 bool ImageBridgeParent::RecvWillClose()
 {
   // If there is any texture still alive we have to force it to deallocate the
@@ -364,17 +352,17 @@ IToplevelProtocol*
 ImageBridgeParent::CloneToplevel(const InfallibleTArray<ProtocolFdMapping>& aFds,
                                  base::ProcessHandle aPeerProcess,
                                  mozilla::ipc::ProtocolCloneContext* aCtx)
 {
   for (unsigned int i = 0; i < aFds.Length(); i++) {
     if (aFds[i].protocolId() == unsigned(GetProtocolId())) {
       Transport* transport = OpenDescriptor(aFds[i].fd(),
                                             Transport::MODE_SERVER);
-      PImageBridgeParent* bridge = Create(transport, base::GetProcId(aPeerProcess), mSubprocess);
+      PImageBridgeParent* bridge = Create(transport, base::GetProcId(aPeerProcess));
       bridge->CloneManagees(this, aCtx);
       bridge->IToplevelProtocol::SetTransport(transport);
       // The reference to the compositor thread is held in OnChannelConnected().
       // We need to do this for cloned actors, too.
       bridge->OnChannelConnected(base::GetProcId(aPeerProcess));
       return bridge;
     }
   }
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -23,17 +23,16 @@ class MessageLoop;
 
 namespace base {
 class Thread;
 } // namespace base
 
 namespace mozilla {
 namespace ipc {
 class Shmem;
-class GeckoChildProcessHost;
 } // namespace ipc
 
 namespace layers {
 
 /**
  * ImageBridgeParent is the manager Protocol of ImageContainerParent.
  * It's purpose is mainly to setup the IPDL connection. Most of the
  * interesting stuff is in ImageContainerParent.
@@ -50,17 +49,17 @@ public:
   ImageBridgeParent(MessageLoop* aLoop, Transport* aTransport, ProcessId aChildProcessId);
   ~ImageBridgeParent();
 
   virtual ShmemAllocator* AsShmemAllocator() override { return this; }
 
   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
 
   static PImageBridgeParent*
-  Create(Transport* aTransport, ProcessId aChildProcessId, ipc::GeckoChildProcessHost* aProcessHost);
+  Create(Transport* aTransport, ProcessId aChildProcessId);
 
   // CompositableParentManager
   virtual void SendAsyncMessage(const InfallibleTArray<AsyncParentMessageData>& aMessage) override;
 
   virtual void NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) override;
 
   virtual base::ProcessId GetChildProcessId() override
   {
@@ -150,18 +149,16 @@ private:
   Transport* mTransport;
   // This keeps us alive until ActorDestroy(), at which point we do a
   // deferred destruction of ourselves.
   RefPtr<ImageBridgeParent> mSelfRef;
 
   bool mSetChildThreadPriority;
   bool mClosed;
 
-  ipc::GeckoChildProcessHost* mSubprocess;
-
   /**
    * Map of all living ImageBridgeParent instances
    */
   static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
 
   static MessageLoop* sMainLoop;
 
   RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
--- a/ipc/chromium/src/chrome/common/process_watcher_win.cc
+++ b/ipc/chromium/src/chrome/common/process_watcher_win.cc
@@ -104,16 +104,16 @@ void ProcessWatcher::EnsureProcessTermin
   DCHECK(process != GetCurrentProcess());
 
   // If already signaled, then we are done!
   if (WaitForSingleObject(process, 0) == WAIT_OBJECT_0) {
     base::CloseProcessHandle(process);
     return;
   }
 
+  MessageLoopForIO* loop = MessageLoopForIO::current();
   if (force) {
     RefPtr<mozilla::Runnable> task = new ChildReaper(process, force);
-    MessageLoop::current()->PostDelayedTask(task.forget(),
-                                            kWaitInterval);
+    loop->PostDelayedTask(task.forget(), kWaitInterval);
   } else {
     loop->AddDestructionObserver(new ChildReaper(process, force));
   }
 }
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -102,17 +102,16 @@ GeckoChildProcessHost::GeckoChildProcess
     mEnableSandboxLogging(false),
     mSandboxLevel(0),
 #endif
     mDelegate(nullptr),
     mChildProcessHandle(0)
 #if defined(MOZ_WIDGET_COCOA)
   , mChildTask(MACH_PORT_NULL)
 #endif
-  , mAssociatedActors(1)
 {
     MOZ_COUNT_CTOR(GeckoChildProcessHost);
 }
 
 GeckoChildProcessHost::~GeckoChildProcessHost()
 
 {
   AssertIOThread();
@@ -482,36 +481,16 @@ GeckoChildProcessHost::SetAlreadyDead()
   if (mChildProcessHandle &&
       mChildProcessHandle != kInvalidProcessHandle) {
     base::CloseProcessHandle(mChildProcessHandle);
   }
 
   mChildProcessHandle = 0;
 }
 
-namespace {
-
-void
-DelayedDeleteSubprocess(GeckoChildProcessHost* aSubprocess)
-{
-  XRE_GetIOMessageLoop()
-    ->PostTask(mozilla::MakeAndAddRef<DeleteTask<GeckoChildProcessHost>>(aSubprocess));
-}
-
-}
-
-void
-GeckoChildProcessHost::DissociateActor()
-{
-  if (!--mAssociatedActors) {
-    MessageLoop::current()->
-      PostTask(NewRunnableFunction(DelayedDeleteSubprocess, this));
-  }
-}
-
 int32_t GeckoChildProcessHost::mChildCounter = 0;
 
 void
 GeckoChildProcessHost::SetChildLogName(const char* varName, const char* origLogName,
                                        nsACString &buffer)
 {
   // We currently have no portable way to launch child with environment
   // different than parent.  So temporarily change NSPR_LOG_FILE so child
--- a/ipc/glue/GeckoChildProcessHost.h
+++ b/ipc/glue/GeckoChildProcessHost.h
@@ -7,17 +7,16 @@
 #ifndef __IPC_GLUE_GECKOCHILDPROCESSHOST_H__
 #define __IPC_GLUE_GECKOCHILDPROCESSHOST_H__
 
 #include "base/file_path.h"
 #include "base/process_util.h"
 #include "base/waitable_event.h"
 #include "chrome/common/child_process_host.h"
 
-#include "mozilla/Atomics.h"
 #include "mozilla/DebugOnly.h"
 #include "mozilla/ipc/FileDescriptor.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/StaticPtr.h"
 
 #include "nsCOMPtr.h"
 #include "nsXULAppAPI.h"        // for GeckoProcessType
 #include "nsString.h"
@@ -123,24 +122,16 @@ public:
    * Must run on the IO thread.  Cause the OS process to exit and
    * ensure its OS resources are cleaned up.
    */
   void Join();
 
   // For bug 943174: Skip the EnsureProcessTerminated call in the destructor.
   void SetAlreadyDead();
 
-  // This associates an actor telling the process host to stay alive at least
-  // until DissociateActor has been called.
-  void AssociateActor() { mAssociatedActors++; }
-
-  // This gets called when actors get destroyed and will schedule the object
-  // for deletion when all actors have cleared their associations.
-  void DissociateActor();
-
   static void EnableSameExecutableForContentProc() { sRunSelfAsContentProc = true; }
 
 protected:
   GeckoProcessType mProcessType;
   ChildPrivileges mPrivileges;
   Monitor mMonitor;
   FilePath mProcessPath;
 
@@ -213,20 +204,16 @@ private:
   // channel, there's a small window of time in which *we* might still
   // be the channel listener, and receive messages.  That's bad
   // because we have no idea what to do with those messages.  So queue
   // them here until we hand off the eventual listener.
   //
   // FIXME/cjones: this strongly indicates bad design.  Shame on us.
   std::queue<IPC::Message> mQueue;
 
-  // This tracks how many actors are associated with this process that require
-  // it to stay alive and have not yet been destroyed.
-  Atomic<int32_t> mAssociatedActors;
-
   // Remember original env values so we can restore it (there is no other
   // simple way how to change environment of a child process than to modify
   // the current environment).
   nsCString mRestoreOrigNSPRLogName;
   nsCString mRestoreOrigMozLogName;
 
   static uint32_t sNextUniqueID;