From e6f04f4af31e299ae9887108ed52eb8966fbf531 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 18 Nov 2015 16:59:06 +0100 Subject: [PATCH] Bug 1219529 - Don't attempt to deallocate shmems after the ipdl protocol is shut down. r=sotaro --- gfx/layers/ipc/ImageBridgeParent.cpp | 38 ++++++++++++++++++++- gfx/layers/ipc/ImageBridgeParent.h | 24 +++++--------- gfx/layers/ipc/LayerTransactionParent.cpp | 40 ++++++++++++++++++++++- gfx/layers/ipc/LayerTransactionParent.h | 13 ++------ 4 files changed, 87 insertions(+), 28 deletions(-) diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index d6462ea465a..9a242cd6aab 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -58,6 +58,7 @@ ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, : mMessageLoop(aLoop) , mTransport(aTransport) , mSetChildThreadPriority(false) + , mStopped(false) { MOZ_ASSERT(NS_IsMainThread()); sMainLoop = MessageLoop::current(); @@ -206,9 +207,12 @@ ReleaseImageBridgeParent(ImageBridgeParent* 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" @@ -383,6 +387,38 @@ 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(); diff --git a/gfx/layers/ipc/ImageBridgeParent.h b/gfx/layers/ipc/ImageBridgeParent.h index 016027c76fb..f13dcdc6b77 100644 --- a/gfx/layers/ipc/ImageBridgeParent.h +++ b/gfx/layers/ipc/ImageBridgeParent.h @@ -100,24 +100,15 @@ public: // 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; @@ -162,6 +153,7 @@ private: RefPtr mSelfRef; bool mSetChildThreadPriority; + bool mStopped; /** * Map of all living ImageBridgeParent instances diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 5daa562c752..f724ec10b7e 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -174,13 +174,19 @@ LayerTransactionParent::RecvShutdown() void LayerTransactionParent::Destroy() { - mDestroyed = true; const ManagedContainer& layers = ManagedPLayerParent(); for (auto iter = layers.ConstIter(); !iter.Done(); iter.Next()) { ShadowLayerParent* slp = static_cast(iter.Get()->GetKey()); slp->Destroy(); } + InfallibleTArray textures; + ManagedPTextureParent(textures); + for (unsigned int i = 0; i < textures.Length(); ++i) { + RefPtr tex = TextureHost::AsTextureHost(textures[i]); + tex->DeallocateDeviceData(); + } + mDestroyed = true; } bool @@ -989,6 +995,38 @@ 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(); diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index 1ad55f8311f..f1bad897362 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -63,20 +63,13 @@ public: // 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;