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 310609 3f73d822655e6ecf078d62eb341145bc9fb3a827
parent 310608 8d5090df5068b890ce6d18e54b12b175b6a482ed
child 310610 f7687a837b4533f5d749d21e7e898793843e2301
push id5513
push userraliiev@mozilla.com
push dateMon, 25 Jan 2016 13:55:34 +0000
treeherdermozilla-beta@5ee97dd05b5c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical, ritu
bugs1223193
milestone45.0a2
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());
   MOZ_ASSERT(aCompositable->IsConnected());
 
@@ -366,17 +369,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)
 {
@@ -458,33 +461,33 @@ void ImageBridgeChild::DispatchReleaseTe
 
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseTextureClientNow, aClient));
 }
 
 static void UpdateImageClientNow(ImageClient* aClient, RefPtr<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;
   }
 
@@ -540,17 +543,17 @@ void ImageBridgeChild::UpdateAsyncCanvas
   sImageBridgeChildSingleton->BeginTransaction();
   aWrapper->GetCanvasClient()->Updated();
   sImageBridgeChildSingleton->EndTransaction();
 }
 
 static void FlushAllImagesSync(ImageClient* aClient, ImageContainer* aContainer,
                                RefPtr<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();
@@ -569,17 +572,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;
@@ -700,16 +703,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();
 
@@ -313,14 +322,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