Ensure that CompositorBridgeChild retains an IPDL ref while owning a Transport. (bug 1314520, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Tue, 08 Nov 2016 15:43:07 -0800
changeset 348476 6cfa59e10e839247e5ee4fb363f52e15d4dae5e9
parent 348475 0e53345bea4fb64be1a7ee9abc29bbc7ebeffd26
child 348477 8f3b77d736fab35338d54166856819db115ce87e
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1314520
milestone52.0a1
Ensure that CompositorBridgeChild retains an IPDL ref while owning a Transport. (bug 1314520, r=mattwoodrow)
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -202,18 +202,17 @@ CompositorBridgeChild::InitForContent(En
   // There's only one compositor per child process.
   MOZ_ASSERT(!sCompositorBridge);
 
   RefPtr<CompositorBridgeChild> child(new CompositorBridgeChild(nullptr));
   if (!aEndpoint.Bind(child)) {
     NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
     return false;
   }
-
-  child->mCanSend = true;
+  child->InitIPDL();
 
   // We release this ref in DeferredDestroyCompositor.
   sCompositorBridge = child;
   return true;
 }
 
 /* static */ bool
 CompositorBridgeChild::ReinitForContent(Endpoint<PCompositorBridgeChild>&& aEndpoint)
@@ -240,40 +239,53 @@ CompositorBridgeChild::InitSameProcess(w
                                        const gfx::IntSize& aSurfaceSize)
 {
   TimeDuration vsyncRate =
     gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
 
   mCompositorBridgeParent =
     new CompositorBridgeParent(aScale, vsyncRate, aUseExternalSurface, aSurfaceSize);
 
-  mCanSend = Open(mCompositorBridgeParent->GetIPCChannel(),
-                  CompositorThreadHolder::Loop(),
-                  ipc::ChildSide);
-  MOZ_RELEASE_ASSERT(mCanSend);
+  bool ok = Open(mCompositorBridgeParent->GetIPCChannel(),
+                 CompositorThreadHolder::Loop(),
+                 ipc::ChildSide);
+  MOZ_RELEASE_ASSERT(ok);
 
+  InitIPDL();
   mCompositorBridgeParent->InitSameProcess(aWidget, aLayerTreeId, aUseAPZ);
   return mCompositorBridgeParent;
 }
 
 /* static */ RefPtr<CompositorBridgeChild>
 CompositorBridgeChild::CreateRemote(const uint64_t& aProcessToken,
                                     ClientLayerManager* aLayerManager,
                                     Endpoint<PCompositorBridgeChild>&& aEndpoint)
 {
   RefPtr<CompositorBridgeChild> child = new CompositorBridgeChild(aLayerManager);
   if (!aEndpoint.Bind(child)) {
     return nullptr;
   }
-
-  child->mCanSend = true;
+  child->InitIPDL();
   child->mProcessToken = aProcessToken;
   return child;
 }
 
+void
+CompositorBridgeChild::InitIPDL()
+{
+  mCanSend = true;
+  AddRef();
+}
+
+void
+CompositorBridgeChild::DeallocPCompositorBridgeChild()
+{
+  Release();
+}
+
 /*static*/ CompositorBridgeChild*
 CompositorBridgeChild::Get()
 {
   // This is only expected to be used in child processes.
   MOZ_ASSERT(!XRE_IsParentProcess());
   return sCompositorBridge;
 }
 
@@ -568,30 +580,23 @@ CompositorBridgeChild::RecvClearCachedRe
   }
   return true;
 }
 
 void
 CompositorBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
 {
   if (aWhy == AbnormalShutdown) {
-#ifdef MOZ_B2G
-  // Due to poor lifetime management of gralloc (and possibly shmems) we will
-  // crash at some point in the future when we get destroyed due to abnormal
-  // shutdown. Its better just to crash here. On desktop though, we have a chance
-  // of recovering.
-    NS_RUNTIMEABORT("ActorDestroy by IPC channel failure at CompositorBridgeChild");
-#endif
-
     // If the parent side runs into a problem then the actor will be destroyed.
     // There is nothing we can do in the child side, here sets mCanSend as false.
-    mCanSend = false;
     gfxCriticalNote << "Receive IPC close with reason=AbnormalShutdown";
   }
 
+  mCanSend = false;
+
   if (mProcessToken && XRE_IsParentProcess()) {
     GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);
   }
 }
 
 bool
 CompositorBridgeChild::RecvSharedCompositorFrameMetrics(
     const mozilla::ipc::SharedMemoryBasic::Handle& metrics,
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -226,16 +226,19 @@ public:
   void ProcessingError(Result aCode, const char* aReason) override;
 
   void WillEndTransaction();
 
 private:
   // Private destructor, to discourage deletion outside of Release():
   virtual ~CompositorBridgeChild();
 
+  void InitIPDL();
+  void DeallocPCompositorBridgeChild() override;
+
   virtual PLayerTransactionChild*
     AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
                                 const uint64_t& aId,
                                 TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                 bool* aSuccess) override;
 
   virtual bool DeallocPLayerTransactionChild(PLayerTransactionChild *aChild) override;