Bug 1219529 - Don't attempt to deallocate shmems after the ipdl protocol is shut down. r=sotaro a=ritu
authorNicolas Silva <nsilva@mozilla.com>
Wed, 18 Nov 2015 16:59:06 +0100
changeset 305630 5c87a2e6268e68311274069a4a82af03ab011574
parent 305629 7d2f0faddb3f07b574471c45b2c13ec18e37bd22
child 305631 1477b8cf6b93fe76aa7cdb9c01a5334074aefdbe
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssotaro, ritu
bugs1219529
milestone44.0a2
Bug 1219529 - Don't attempt to deallocate shmems after the ipdl protocol is shut down. r=sotaro a=ritu
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
gfx/layers/ipc/LayerTransactionParent.h
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -53,16 +53,17 @@ MessageLoop* ImageBridgeParent::sMainLoo
 CompositorThreadHolder* GetCompositorThreadHolder();
 
 ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop,
                                      Transport* aTransport,
                                      ProcessId aChildProcessId)
   : mMessageLoop(aLoop)
   , mTransport(aTransport)
   , mSetChildThreadPriority(false)
+  , mStopped(false)
 {
   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
@@ -201,19 +202,22 @@ bool ImageBridgeParent::RecvWillStop()
 static void
 ReleaseImageBridgeParent(ImageBridgeParent* aImageBridgeParent)
 {
   RELEASE_MANUALLY(aImageBridgeParent);
 }
 
 bool ImageBridgeParent::RecvStop()
 {
-  // This message just serves as synchronization between the
+  // This message mostly serves as synchronization between the
   // child and parent threads during shutdown.
 
+  // Can't alloc/dealloc shmems from now on.
+  mStopped = true;
+
   // There is one thing that we need to do here: temporarily addref, so that
   // the handling of this sync message can't race with the destruction of
   // the ImageBridgeParent, which would trigger the dreaded "mismatched CxxStackFrames"
   // assertion of MessageChannel.
   ADDREF_MANUALLY(this);
   MessageLoop::current()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseImageBridgeParent, this));
@@ -378,16 +382,48 @@ ImageBridgeParent::CloneToplevel(const I
 }
 
 void
 ImageBridgeParent::OnChannelConnected(int32_t aPid)
 {
   mCompositorThreadHolder = GetCompositorThreadHolder();
 }
 
+
+bool
+ImageBridgeParent::AllocShmem(size_t aSize,
+                ipc::SharedMemory::SharedMemoryType aType,
+                ipc::Shmem* aShmem)
+{
+  if (mStopped) {
+    return false;
+  }
+  return PImageBridgeParent::AllocShmem(aSize, aType, aShmem);
+}
+
+bool
+ImageBridgeParent::AllocUnsafeShmem(size_t aSize,
+                      ipc::SharedMemory::SharedMemoryType aType,
+                      ipc::Shmem* aShmem)
+{
+  if (mStopped) {
+    return false;
+  }
+  return PImageBridgeParent::AllocUnsafeShmem(aSize, aType, aShmem);
+}
+
+void
+ImageBridgeParent::DeallocShmem(ipc::Shmem& aShmem)
+{
+  if (mStopped) {
+    return;
+  }
+  PImageBridgeParent::DeallocShmem(aShmem);
+}
+
 bool ImageBridgeParent::IsSameProcess() const
 {
   return OtherPid() == base::GetCurrentProcId();
 }
 
 void
 ImageBridgeParent::ReplyRemoveTexture(const OpReplyRemoveTexture& aReply)
 {
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -95,34 +95,25 @@ public:
   // Shutdown step 2
   virtual bool RecvStop() override;
 
   virtual MessageLoop* GetMessageLoop() const override;
 
 
   // ISurfaceAllocator
 
-  bool AllocShmem(size_t aSize,
-                  ipc::SharedMemory::SharedMemoryType aType,
-                  ipc::Shmem* aShmem) override
-  {
-    return PImageBridgeParent::AllocShmem(aSize, aType, aShmem);
-  }
+  virtual bool AllocShmem(size_t aSize,
+                          ipc::SharedMemory::SharedMemoryType aType,
+                          ipc::Shmem* aShmem) override;
 
-  bool AllocUnsafeShmem(size_t aSize,
-                        ipc::SharedMemory::SharedMemoryType aType,
-                        ipc::Shmem* aShmem) override
-  {
-    return PImageBridgeParent::AllocUnsafeShmem(aSize, aType, aShmem);
-  }
+  virtual bool AllocUnsafeShmem(size_t aSize,
+                                ipc::SharedMemory::SharedMemoryType aType,
+                                ipc::Shmem* aShmem) override;
 
-  void DeallocShmem(ipc::Shmem& aShmem) override
-  {
-    PImageBridgeParent::DeallocShmem(aShmem);
-  }
+  virtual void DeallocShmem(ipc::Shmem& aShmem) override;
 
   virtual bool IsSameProcess() const override;
 
   virtual void ReplyRemoveTexture(const OpReplyRemoveTexture& aReply) override;
 
   static void ReplyRemoveTexture(base::ProcessId aChildProcessId,
                                  const OpReplyRemoveTexture& aReply);
 
@@ -157,16 +148,17 @@ private:
   void DeferredDestroy();
   MessageLoop* mMessageLoop;
   Transport* mTransport;
   // This keeps us alive until ActorDestroy(), at which point we do a
   // deferred destruction of ourselves.
   RefPtr<ImageBridgeParent> mSelfRef;
 
   bool mSetChildThreadPriority;
+  bool mStopped;
 
   /**
    * Map of all living ImageBridgeParent instances
    */
   static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
 
   static MessageLoop* sMainLoop;
 
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -169,23 +169,29 @@ LayerTransactionParent::RecvShutdown()
 {
   Destroy();
   return Send__delete__(this);
 }
 
 void
 LayerTransactionParent::Destroy()
 {
-  mDestroyed = true;
   const ManagedContainer<PLayerParent>& layers = ManagedPLayerParent();
   for (auto iter = layers.ConstIter(); !iter.Done(); iter.Next()) {
     ShadowLayerParent* slp =
       static_cast<ShadowLayerParent*>(iter.Get()->GetKey());
     slp->Destroy();
   }
+  InfallibleTArray<PTextureParent*> textures;
+  ManagedPTextureParent(textures);
+  for (unsigned int i = 0; i < textures.Length(); ++i) {
+    RefPtr<TextureHost> tex = TextureHost::AsTextureHost(textures[i]);
+    tex->DeallocateDeviceData();
+  }
+  mDestroyed = true;
 }
 
 bool
 LayerTransactionParent::RecvUpdateNoSwap(InfallibleTArray<Edit>&& cset,
                                          const uint64_t& aTransactionId,
                                          const TargetConfig& targetConfig,
                                          PluginsArray&& aPlugins,
                                          const bool& isFirstPaint,
@@ -980,16 +986,48 @@ LayerTransactionParent::RecvChildAsyncMe
   return true;
 }
 
 void
 LayerTransactionParent::ActorDestroy(ActorDestroyReason why)
 {
 }
 
+bool
+LayerTransactionParent::AllocShmem(size_t aSize,
+                                   ipc::SharedMemory::SharedMemoryType aType,
+                                   ipc::Shmem* aShmem)
+{
+  if (!mIPCOpen || mDestroyed) {
+    return false;
+  }
+  return PLayerTransactionParent::AllocShmem(aSize, aType, aShmem);
+}
+
+bool
+LayerTransactionParent::AllocUnsafeShmem(size_t aSize,
+                                         ipc::SharedMemory::SharedMemoryType aType,
+                                         ipc::Shmem* aShmem)
+{
+  if (!mIPCOpen || mDestroyed) {
+    return false;
+  }
+
+  return PLayerTransactionParent::AllocUnsafeShmem(aSize, aType, aShmem);
+}
+
+void
+LayerTransactionParent::DeallocShmem(ipc::Shmem& aShmem)
+{
+  if (!mIPCOpen || mDestroyed) {
+    return;
+  }
+  PLayerTransactionParent::DeallocShmem(aShmem);
+}
+
 bool LayerTransactionParent::IsSameProcess() const
 {
   return OtherPid() == base::GetCurrentProcId();
 }
 
 void
 LayerTransactionParent::SendFenceHandleIfPresent(PTextureParent* aTexture,
                                                  CompositableHost* aCompositableHost)
--- a/gfx/layers/ipc/LayerTransactionParent.h
+++ b/gfx/layers/ipc/LayerTransactionParent.h
@@ -58,30 +58,23 @@ public:
   LayerManagerComposite* layer_manager() const { return mLayerManager; }
 
   uint64_t GetId() const { return mId; }
   Layer* GetRoot() const { return mRoot; }
 
   // ISurfaceAllocator
   virtual bool AllocShmem(size_t aSize,
                           ipc::SharedMemory::SharedMemoryType aType,
-                          ipc::Shmem* aShmem) override {
-    return PLayerTransactionParent::AllocShmem(aSize, aType, aShmem);
-  }
+                          ipc::Shmem* aShmem) override;
 
   virtual bool AllocUnsafeShmem(size_t aSize,
                                 ipc::SharedMemory::SharedMemoryType aType,
-                                ipc::Shmem* aShmem) override {
-    return PLayerTransactionParent::AllocUnsafeShmem(aSize, aType, aShmem);
-  }
+                                ipc::Shmem* aShmem) override;
 
-  virtual void DeallocShmem(ipc::Shmem& aShmem) override
-  {
-    PLayerTransactionParent::DeallocShmem(aShmem);
-  }
+  virtual void DeallocShmem(ipc::Shmem& aShmem) override;
 
   virtual bool IsSameProcess() const override;
 
   const uint64_t& GetPendingTransactionId() { return mPendingTransaction; }
   void SetPendingTransactionId(uint64_t aId) { mPendingTransaction = aId; }
 
   // CompositableParentManager
   virtual void SendFenceHandleIfPresent(PTextureParent* aTexture,