Don't access ShadowableLayer from ClientLayer's destructor. (bug 1323539 part 1, r=mattwoodrow)
authorDavid Anderson <danderson@mozilla.com>
Wed, 21 Dec 2016 10:43:04 -0500
changeset 452476 da479aa758a8e5eee2583da370bfdac2ca819999
parent 452475 4e9e1f7ef5a8a6a8e88ef36e8aeb997136eb0d75
child 452477 11873cde7a5992d3b721abc17b35ff8f28dae0ae
push id39415
push usermozilla@noorenberghe.ca
push dateWed, 21 Dec 2016 20:49:14 +0000
reviewersmattwoodrow
bugs1323539
milestone53.0a1
Don't access ShadowableLayer from ClientLayer's destructor. (bug 1323539 part 1, r=mattwoodrow)
gfx/layers/client/ClientLayerManager.cpp
gfx/layers/client/ClientLayerManager.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -891,16 +891,13 @@ ClientLayerManager::CreatePersistentBuff
   }
 
   return LayerManager::CreatePersistentBufferProvider(aSize, aFormat);
 }
 
 
 ClientLayer::~ClientLayer()
 {
-  if (HasShadow()) {
-    PLayerChild::Send__delete__(GetShadow());
-  }
   MOZ_COUNT_DTOR(ClientLayer);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/client/ClientLayerManager.h
+++ b/gfx/layers/client/ClientLayerManager.h
@@ -346,30 +346,24 @@ class ClientLayer : public ShadowableLay
 public:
   ClientLayer()
   {
     MOZ_COUNT_CTOR(ClientLayer);
   }
 
   ~ClientLayer();
 
-  void SetShadow(PLayerChild* aShadow)
-  {
-    MOZ_ASSERT(!mShadow, "can't have two shadows (yet)");
-    mShadow = aShadow;
-  }
-
   virtual void Disconnect()
   {
     // This is an "emergency Disconnect()", called when the compositing
     // process has died.  |mShadow| and our Shmem buffers are
     // automatically managed by IPDL, so we don't need to explicitly
     // free them here (it's hard to get that right on emergency
     // shutdown anyway).
-    mShadow = nullptr;
+    SetShadow(nullptr);
   }
 
   virtual void ClearCachedResources() { }
 
   // Shrink memory usage.
   // Called when "memory-pressure" is observed.
   virtual void HandleMemoryPressure() { }
 
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -1054,10 +1054,17 @@ void
 ShadowLayerForwarder::SyncWithCompositor()
 {
   auto compositorBridge = GetCompositorBridgeChild();
   if (compositorBridge && compositorBridge->IPCOpen()) {
     compositorBridge->SendSyncWithCompositor();
   }
 }
 
+ShadowableLayer::~ShadowableLayer()
+{
+  if (HasShadow()) {
+    PLayerChild::Send__delete__(GetShadow());
+  }
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -444,34 +444,41 @@ class CompositableClient;
  * through a ShadowLayerForwarder.  A ShadowableLayer maps to a
  * Shadow*Layer in a parent context.
  *
  * Note that ShadowLayers can themselves be ShadowableLayers.
  */
 class ShadowableLayer
 {
 public:
-  virtual ~ShadowableLayer() {}
+  virtual ~ShadowableLayer();
 
   virtual Layer* AsLayer() = 0;
 
   /**
    * True if this layer has a shadow in a parent process.
    */
   bool HasShadow() { return !!mShadow; }
 
   /**
    * Return the IPC handle to a Shadow*Layer referring to this if one
    * exists, nullptr if not.
    */
   PLayerChild* GetShadow() { return mShadow; }
 
+  void SetShadow(PLayerChild* aShadow) {
+    MOZ_ASSERT(!mShadow || !aShadow, "can't have two shadows (yet)");
+    mShadow = aShadow;
+  }
+
   virtual CompositableClient* GetCompositableClient() { return nullptr; }
+
 protected:
   ShadowableLayer() : mShadow(nullptr) {}
 
+private:
   PLayerChild* mShadow;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // ifndef mozilla_layers_ShadowLayers_h