Bug 826829 - Change ImageContainerChild::DispatchSetIdle() to synchronous SetIdle(). r=kanru
authorSotaro Ikeda <sikeda@mozilla.com>
Mon, 14 Jan 2013 20:15:03 -0500
changeset 118840 4966fa10cf1da556ef0e5169156d007b48d6b62f
parent 118839 9bc194aa7e149c0fd13db0969026bbfb1a1ab96c
child 118841 49007a675939b70d2c2fdee0c3d7850f6921c808
push id24180
push useremorley@mozilla.com
push dateTue, 15 Jan 2013 22:58:27 +0000
treeherdermozilla-central@72e34ce7fd92 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskanru
bugs826829
milestone21.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 826829 - Change ImageContainerChild::DispatchSetIdle() to synchronous SetIdle(). r=kanru
gfx/layers/ImageContainer.cpp
gfx/layers/ipc/ImageContainerChild.cpp
gfx/layers/ipc/ImageContainerChild.h
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -178,17 +178,17 @@ void
 ImageContainer::SetCurrentImage(Image *aImage)
 {
   ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
   if (mImageContainerChild) {
     if (aImage) {
       mImageContainerChild->SendImageAsync(this, aImage);
     } else {
-      mImageContainerChild->DispatchSetIdle();
+      mImageContainerChild->SetIdle();
     }
   }
   
   SetCurrentImageInternal(aImage);
 }
 
 void
 ImageContainer::SetCurrentImageInTransaction(Image *aImage)
--- a/gfx/layers/ipc/ImageContainerChild.cpp
+++ b/gfx/layers/ipc/ImageContainerChild.cpp
@@ -68,22 +68,43 @@ void ImageContainerChild::SetIdleNow()
 {
   if (mStop) return;
 
   SendFlush();
   ClearSharedImagePool();
   mImageQueue.Clear();
 }
 
-void ImageContainerChild::DispatchSetIdle()
+void ImageContainerChild::SetIdleSync(Monitor* aBarrier, bool* aDone)
+{
+  MonitorAutoLock autoMon(*aBarrier);
+
+  SetIdleNow();
+  *aDone = true;
+  aBarrier->NotifyAll();
+}
+
+void ImageContainerChild::SetIdle()
 {
   if (mStop) return;
 
+  if (InImageBridgeChildThread()) {
+    return SetIdleNow();
+  }
+
+  Monitor barrier("SetIdle Lock");
+  MonitorAutoLock autoMon(barrier);
+  bool done = false;
+
   GetMessageLoop()->PostTask(FROM_HERE, 
-                    NewRunnableMethod(this, &ImageContainerChild::SetIdleNow));
+                    NewRunnableMethod(this, &ImageContainerChild::SetIdleSync, &barrier, &done));
+
+  while (!done) {
+    barrier.Wait();
+  }
 }
 
 void ImageContainerChild::StopChildAndParent()
 {
   if (mStop) {
     return;
   }
   mStop = true;    
--- a/gfx/layers/ipc/ImageContainerChild.h
+++ b/gfx/layers/ipc/ImageContainerChild.h
@@ -101,26 +101,19 @@ public:
 
   /**
    * Dispatches a task to the ImageBridge Thread, that will destroy the 
    * ImageContainerChild and associated imageContainerParent asynchonously.
    */
   void DispatchDestroy();
 
   /**
-   * Dispatches a task on the ImageBridgeChild's thread that will call SendFlush
-   * and deallocate the shared images in the pool.
-   * Can be called on any thread.
+   * Flush and deallocate the shared images in the pool.
    */
-  void DispatchSetIdle();
-
-  /**
-   * Must be called on the ImageBridgeChild's thread.
-   */
-  void SetIdleNow();
+  void SetIdle();
 
   /**
    * Can be called from any thread.
    * deallocates or places aImage in a pool.
    * If this method is not called on the ImageBridgeChild thread, a task is
    * is dispatched and the recycling/deallocation happens asynchronously on
    * the ImageBridgeChild thread.
    */
@@ -163,19 +156,31 @@ protected:
   { return false; }
 
   inline MessageLoop* GetMessageLoop() const 
   {
     return ImageBridgeChild::GetSingleton()->GetMessageLoop();
   }
 
   /**
-   * Must be called on the ImageBridgeCHild's thread.
+   * Must be called on the ImageBridgeChild's thread.
    */
   void DestroyNow();
+  
+  /**
+   * Dispatches a task on the ImageBridgeChild's thread that will call SendFlush
+   * and deallocate the shared images in the pool.
+   * Can be called on any thread.
+   */
+  void SetIdleSync(Monitor* aBarrier, bool* aDone);
+
+  /**
+   * Must be called on the ImageBridgeChild's thread.
+   */
+  void SetIdleNow();
 
   inline void SetID(uint64_t id)
   {
     mImageContainerID = id;
   }
 
   /**
    * Must be called on the ImageBirdgeChild thread. (See RecycleSharedImage)