Bug 1003893 - Ensure that the delete of RasterImage occurs on the main thread. r=seth, a=sylvestre
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 16 Jun 2014 22:05:00 -0400
changeset 200595 9bf59a51e04d8ed883c5a41a2c715cfaea259303
parent 200594 cc6044083858a5e1d895b26f513610ce0fa1c2bb
child 200596 4de57e02872ec9aad17b85814ed5dd02f63ad335
push id486
push userasasaki@mozilla.com
push dateMon, 14 Jul 2014 18:39:42 +0000
treeherdermozilla-release@d33428174ff1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth, sylvestre
bugs1003893
milestone31.0
Bug 1003893 - Ensure that the delete of RasterImage occurs on the main thread. r=seth, a=sylvestre Dispatch nsRefPtr<RasterImage> to the main thread by NS_ProxyRelease to avoid RasterImage from being destructed by the DecodeJob thread. (If gMultithreadedDecoding is true.) Therefore, DiscardTracker can safely access RasterImage::Discard() by the raw pointer in DiscardTracker::Node.
image/src/RasterImage.cpp
image/src/RasterImage.h
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -3417,16 +3417,32 @@ RasterImage::DecodePool::DecodeJob::Run(
   } else {
     // Nothing more for us to do - let everyone know what happened.
     DecodeDoneWorker::NotifyFinishedSomeDecoding(mImage, mRequest);
   }
 
   return NS_OK;
 }
 
+RasterImage::DecodePool::DecodeJob::~DecodeJob()
+{
+  if (gMultithreadedDecoding) {
+    // Dispatch mImage to main thread to prevent mImage from being destructed by decode thread.
+    nsCOMPtr<nsIThread> mainThread = do_GetMainThread();
+    NS_WARN_IF_FALSE(mainThread, "Couldn't get the main thread!");
+    if (mainThread) {
+      // Handle ambiguous nsISupports inheritance
+      RasterImage* rawImg = nullptr;
+      mImage.swap(rawImg);
+      DebugOnly<nsresult> rv = NS_ProxyRelease(mainThread, NS_ISUPPORTS_CAST(ImageResource*, rawImg));
+      MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to proxy release to main thread");
+    }
+  }
+}
+
 nsresult
 RasterImage::DecodePool::DecodeUntilSizeAvailable(RasterImage* aImg)
 {
   MOZ_ASSERT(NS_IsMainThread());
   ReentrantMonitorAutoEnter lock(aImg->mDecodingMonitor);
 
   if (aImg->mDecodeRequest) {
     // If the image is waiting for decode work to be notified, go ahead and do that.
--- a/image/src/RasterImage.h
+++ b/image/src/RasterImage.h
@@ -478,16 +478,19 @@ private:
     public:
       DecodeJob(DecodeRequest* aRequest, RasterImage* aImg)
         : mRequest(aRequest)
         , mImage(aImg)
       {}
 
       NS_IMETHOD Run();
 
+    protected:
+      virtual ~DecodeJob();
+
     private:
       nsRefPtr<DecodeRequest> mRequest;
       nsRefPtr<RasterImage> mImage;
     };
 
   private: /* members */
 
     // mThreadPoolMutex protects mThreadPool. For all RasterImages R,