Bug 1223193: P2. Cancel ImageBridge proxy functions if shutdown has started. r=nical a=ritu
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 30 Dec 2015 16:52:41 +1100
changeset 305950 cf6974b887316b7744f1de3a4317f8916057f90b
parent 305949 0ea89d1db1752c0fc6a0f742e285e64991f19de1
child 305951 4e8b2e5c39d6171904d136d30922f46fb2b3f5ad
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)
reviewersnical, ritu
bugs1223193
milestone44.0
Bug 1223193: P2. Cancel ImageBridge proxy functions if shutdown has started. r=nical a=ritu
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -103,16 +103,19 @@ struct CompositableTransaction
 };
 
 struct AutoEndTransaction {
   explicit AutoEndTransaction(CompositableTransaction* aTxn) : mTxn(aTxn) {}
   ~AutoEndTransaction() { mTxn->End(); }
   CompositableTransaction* mTxn;
 };
 
+/* static */
+Atomic<bool> ImageBridgeChild::sIsShutDown(false);
+
 void
 ImageBridgeChild::UseTextures(CompositableClient* aCompositable,
                               const nsTArray<TimedTextureClient>& aTextures)
 {
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aCompositable->GetIPDLActor());
 
   nsAutoTArray<TimedTexture,4> textures;
@@ -361,17 +364,17 @@ ConnectImageBridgeInChildProcess(Transpo
 
 static void ReleaseImageClientNow(ImageClient* aClient,
                                   PImageContainerChild* aChild)
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   if (aClient) {
     aClient->Release();
   }
-  if (aChild && ImageBridgeChild::IsCreated()) {
+  if (aChild && ImageBridgeChild::IsCreated() && !ImageBridgeChild::IsShutDown()) {
     aChild->SendAsyncDelete();
   }
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient,
                                                   PImageContainerChild* aChild)
 {
@@ -453,33 +456,33 @@ void ImageBridgeChild::DispatchReleaseTe
 
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseTextureClientNow, aClient));
 }
 
 static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContainer)
 {
-  if (!ImageBridgeChild::IsCreated()) {
+  if (!ImageBridgeChild::IsCreated() || ImageBridgeChild::IsShutDown()) {
     NS_WARNING("Something is holding on to graphics resources after the shutdown"
                "of the graphics subsystem!");
     return;
   }
   MOZ_ASSERT(aClient);
   MOZ_ASSERT(aContainer);
   sImageBridgeChildSingleton->BeginTransaction();
   aClient->UpdateImage(aContainer, Layer::CONTENT_OPAQUE);
   sImageBridgeChildSingleton->EndTransaction();
 }
 
 // static
 void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
                                                  ImageContainer* aContainer)
 {
-  if (!ImageBridgeChild::IsCreated()) {
+  if (!ImageBridgeChild::IsCreated() || ImageBridgeChild::IsShutDown()) {
     NS_WARNING("Something is holding on to graphics resources after the shutdown"
                "of the graphics subsystem!");
     return;
   }
   if (!aClient || !aContainer || !IsCreated()) {
     return;
   }
 
@@ -538,17 +541,17 @@ void ImageBridgeChild::UpdateAsyncCanvas
   sImageBridgeChildSingleton->BeginTransaction();
   aWrapper->GetCanvasClient()->Updated();
   sImageBridgeChildSingleton->EndTransaction();
 }
 
 static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer,
                                AsyncTransactionWaiter* aWaiter)
 {
-  if (!ImageBridgeChild::IsCreated()) {
+  if (!ImageBridgeChild::IsCreated() || ImageBridgeChild::IsShutDown()) {
     // How sad. If we get into this branch it means that the ImageBridge
     // got destroyed between the time we ImageBridgeChild::FlushAllImage
     // was called on some thread, and the time this function was proxied
     // to the ImageBridge thread. ImageBridge gets destroyed way to late
     // in the shutdown of gecko for this to be happening for a good reason.
     NS_WARNING("Something is holding on to graphics resources after the shutdown"
                "of the graphics subsystem!");
     aWaiter->DecrementWaitCount();
@@ -567,17 +570,17 @@ static void FlushAllImagesSync(ImageClie
   // Otherwise, aWaiter will be ready to complete now.
   aWaiter->DecrementWaitCount();
 }
 
 // static
 void ImageBridgeChild::FlushAllImages(ImageClient* aClient,
                                       ImageContainer* aContainer)
 {
-  if (!IsCreated()) {
+  if (!IsCreated() || IsShutDown()) {
     return;
   }
   MOZ_ASSERT(aClient);
   MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
   MOZ_ASSERT(!InImageBridgeChildThread());
   if (InImageBridgeChildThread()) {
     NS_ERROR("ImageBridgeChild::FlushAllImages() is called on ImageBridge thread.");
     return;
@@ -698,16 +701,19 @@ ImageBridgeChild::StartUpInChildProcess(
                         sImageBridgeChildSingleton.get()));
 
   return sImageBridgeChildSingleton;
 }
 
 void ImageBridgeChild::ShutDown()
 {
   MOZ_ASSERT(NS_IsMainThread());
+
+  sIsShutDown = true;
+
   if (ImageBridgeChild::IsCreated()) {
     MOZ_ASSERT(!sImageBridgeChildSingleton->mShuttingDown);
 
     {
       ReentrantMonitor barrier("ImageBridge ShutdownStep1 lock");
       ReentrantMonitorAutoEnter autoMon(barrier);
 
       bool done = false;
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -136,16 +136,25 @@ public:
   static bool StartUpOnThread(base::Thread* aThread);
 
   /**
    * Returns true if the singleton has been created.
    *
    * Can be called from any thread.
    */
   static bool IsCreated();
+  /**
+   * Returns true if the singleton's ShutDown() was called.
+   *
+   * Can be called from any thread.
+   */
+  static bool IsShutDown()
+  {
+    return sIsShutDown;
+  }
 
   /**
    * returns the singleton instance.
    *
    * can be called from any thread.
    */
   static ImageBridgeChild* GetSingleton();
 
@@ -315,14 +324,15 @@ protected:
   ImageBridgeChild();
   bool DispatchAllocShmemInternal(size_t aSize,
                                   SharedMemory::SharedMemoryType aType,
                                   Shmem* aShmem,
                                   bool aUnsafe);
 
   CompositableTransaction* mTxn;
   Atomic<bool> mShuttingDown;
+  static Atomic<bool> sIsShutDown;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif