From 78d126ab89bdd368e44bf1caa67dedf78bf9bfd1 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 12 Jan 2011 14:13:41 -0600 Subject: [PATCH] Bug 623728: Don't process transactions on destroyed shadow layer managers, even when the layer manager hasn't been explicitly destroyed. r=jrmuizel a=b --- gfx/layers/ipc/ShadowLayersParent.cpp | 4 +++- gfx/layers/ipc/ShadowLayersParent.h | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/gfx/layers/ipc/ShadowLayersParent.cpp b/gfx/layers/ipc/ShadowLayersParent.cpp index 06e22d1ac185..9c742047d183 100644 --- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -122,6 +122,7 @@ ShadowChild(const OpRemoveChild& op) //-------------------------------------------------- // ShadowLayersParent ShadowLayersParent::ShadowLayersParent(ShadowLayerManager* aManager) + : mDestroyed(false) { MOZ_COUNT_CTOR(ShadowLayersParent); mLayerManager = aManager; @@ -135,6 +136,7 @@ ShadowLayersParent::~ShadowLayersParent() void ShadowLayersParent::Destroy() { + mDestroyed = true; for (size_t i = 0; i < ManagedPLayerParent().Length(); ++i) { ShadowLayerParent* slp = static_cast(ManagedPLayerParent()[i]); @@ -148,7 +150,7 @@ ShadowLayersParent::RecvUpdate(const InfallibleTArray& cset, { MOZ_LAYERS_LOG(("[ParentSide] recieved txn with %d edits", cset.Length())); - if (layer_manager()->IsDestroyed()) { + if (mDestroyed || layer_manager()->IsDestroyed()) { return true; } diff --git a/gfx/layers/ipc/ShadowLayersParent.h b/gfx/layers/ipc/ShadowLayersParent.h index aad9d63bfe1b..2324171dce1d 100644 --- a/gfx/layers/ipc/ShadowLayersParent.h +++ b/gfx/layers/ipc/ShadowLayersParent.h @@ -86,6 +86,20 @@ private: // Hold the root because it might be grafted under various // containers in the "real" layer tree nsRefPtr mRoot; + // When the widget/frame/browser stuff in this process begins its + // destruction process, we need to Disconnect() all the currently + // live shadow layers, because some of them might be orphaned from + // the layer tree. This happens in Destroy() above. After we + // Destroy() ourself, there's a window in which that information + // hasn't yet propagated back to the child side and it might still + // 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. + bool mDestroyed; }; } // namespace layers