Bug 924622 - Make sure gfx's ipc shutdown happens before shutting down xpcom threads. r=bsmedberg, sotaro
☠☠ backed out by 26209c172150 ☠ ☠
authorNicolas Silva <nical@mozilla.com>
Tue, 15 Apr 2014 11:34:33 +0200
changeset 197051 e17d61d6acf688fa6bec1b98b201dcdde47de5b6
parent 197050 b5c65cbb4b1ae5468ad1f93b6c6974507f42e38f
child 197052 f2808e5f4afe113d914b6e332411c765d6a3b06b
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, sotaro
bugs924622
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 924622 - Make sure gfx's ipc shutdown happens before shutting down xpcom threads. r=bsmedberg, sotaro
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/thebes/gfxPlatform.cpp
xpcom/build/nsXPComInit.cpp
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -326,30 +326,38 @@ static void ReleaseImageClientNow(ImageC
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   aClient->Release();
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseImageClient(ImageClient* aClient)
 {
+  if (!IsCreated()) {
+    return;
+  }
+
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseImageClientNow, aClient));
 }
 
 static void ReleaseTextureClientNow(TextureClient* aClient)
 {
   MOZ_ASSERT(InImageBridgeChildThread());
   aClient->Release();
 }
 
 // static
 void ImageBridgeChild::DispatchReleaseTextureClient(TextureClient* aClient)
 {
+  if (!IsCreated()) {
+    return;
+  }
+
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction(&ReleaseTextureClientNow, aClient));
 }
 
 static void UpdateImageClientNow(ImageClient* aClient, ImageContainer* aContainer)
 {
   MOZ_ASSERT(aClient);
@@ -359,16 +367,20 @@ static void UpdateImageClientNow(ImageCl
   aClient->OnTransaction();
   sImageBridgeChildSingleton->EndTransaction();
 }
 
 //static
 void ImageBridgeChild::DispatchImageClientUpdate(ImageClient* aClient,
                                                  ImageContainer* aContainer)
 {
+  if (!IsCreated()) {
+    return;
+  }
+
   if (InImageBridgeChildThread()) {
     UpdateImageClientNow(aClient, aContainer);
     return;
   }
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
     FROM_HERE,
     NewRunnableFunction<
       void (*)(ImageClient*, ImageContainer*),
@@ -383,16 +395,20 @@ static void FlushAllImagesSync(ImageClie
   ReentrantMonitorAutoEnter autoMon(*aBarrier);
   *aDone = true;
   aBarrier->NotifyAll();
 }
 
 //static
 void ImageBridgeChild::FlushAllImages(ImageClient* aClient, ImageContainer* aContainer, bool aExceptFront)
 {
+  if (!IsCreated()) {
+    return;
+  }
+
   if (InImageBridgeChildThread()) {
     FlushAllImagesNow(aClient, aContainer, aExceptFront);
     return;
   }
 
   ReentrantMonitor barrier("CreateImageClient Lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
   bool done = false;
@@ -572,25 +588,24 @@ bool ImageBridgeChild::StartUpOnThread(T
     return true;
   } else {
     return false;
   }
 }
 
 void ImageBridgeChild::DestroyBridge()
 {
+  if (!IsCreated()) {
+    return;
+  }
   NS_ABORT_IF_FALSE(!InImageBridgeChildThread(),
                     "This method must not be called in this thread.");
   // ...because we are about to dispatch synchronous messages to the
   // ImageBridgeChild thread.
 
-  if (!IsCreated()) {
-    return;
-  }
-
   ReentrantMonitor barrier("ImageBridgeDestroyTask lock");
   ReentrantMonitorAutoEnter autoMon(barrier);
 
   bool done = false;
   sImageBridgeChildSingleton->GetMessageLoop()->PostTask(FROM_HERE,
                   NewRunnableFunction(&StopImageBridgeSync, &barrier, &done));
   while (!done) {
     barrier.Wait();
@@ -602,17 +617,18 @@ void ImageBridgeChild::DestroyBridge()
   while (!done) {
     barrier.Wait();
   }
 
 }
 
 bool InImageBridgeChildThread()
 {
-  return sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId();
+  return ImageBridgeChild::IsCreated() &&
+    sImageBridgeChildThread->thread_id() == PlatformThread::CurrentId();
 }
 
 MessageLoop * ImageBridgeChild::GetMessageLoop() const
 {
   return sImageBridgeChildThread->message_loop();
 }
 
 void ImageBridgeChild::ConnectAsync(ImageBridgeParent* aParent)
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -486,22 +486,16 @@ gfxPlatform::Shutdown()
     // most platforms.  Windows is a "special snowflake", though, and has three
     // context providers available, so we have to shut all of them down.
     // We should only support the default GL provider on Windows; then, this
     // could go away. Unfortunately, we currently support WGL (the default) for
     // WebGL on Optimus.
     mozilla::gl::GLContextProviderEGL::Shutdown();
 #endif
 
-    // This will block this thread untill the ImageBridge protocol is completely
-    // deleted.
-    ImageBridgeChild::ShutDown();
-
-    CompositorParent::ShutDown();
-
     delete gGfxPlatformPrefsLock;
 
     gfxPrefs::DestroySingleton();
     gfxFont::DestroySingletons();
 
     delete gPlatform;
     gPlatform = nullptr;
 }
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -121,16 +121,19 @@ extern nsresult nsStringInputStreamConst
 #include "base/command_line.h"
 #include "base/message_loop.h"
 
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/AvailableMemoryTracker.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/SystemMemoryReporter.h"
 
+#include "mozilla/layers/ImageBridgeChild.h"
+#include "mozilla/layers/CompositorParent.h"
+
 #ifdef MOZ_VISUAL_EVENT_TRACER
 #include "mozilla/VisualEventTracer.h"
 #endif
 
 #include "ogg/ogg.h"
 #ifdef MOZ_VPX
 #include "vpx_mem/vpx_mem.h"
 #endif
@@ -737,16 +740,21 @@ ShutdownXPCOM(nsIServiceManager* servMgr
             if (NS_SUCCEEDED(rv))
             {
                 (void) observerService->
                     NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
                                     nullptr);
             }
         }
 
+        // This must happen after the shutdown of media and widgets, which
+        // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
+        mozilla::layers::ImageBridgeChild::ShutDown();
+        mozilla::layers::CompositorParent::ShutDown();
+
         NS_ProcessPendingEvents(thread);
         mozilla::scache::StartupCache::DeleteSingleton();
         if (observerService)
             (void) observerService->
                 NotifyObservers(nullptr, NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
                                 nullptr);
 
         gXPCOMThreadsShutDown = true;