Bug 1003893 - Ensure that the delete of RasterImage occurs on the main thread. r=seth, a=1.4+
authorBoris Chiou <boris.chiou@gmail.com>
Mon, 16 Jun 2014 22:05:00 -0400
changeset 188072 3722afcbbc51d46ad9c9eacf53c794fe8184bc91
parent 188071 b0696e41d26c383b39f7ed7b80b78b82c2e4bb33
child 188073 b03b0d2e56a91011aefe224b541dcd7589b8dc70
push id389
push userryanvm@gmail.com
push dateTue, 17 Jun 2014 20:24:49 +0000
treeherdermozilla-b2g30_v1_4@3722afcbbc51 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersseth, 1
bugs1003893
milestone30.0
Bug 1003893 - Ensure that the delete of RasterImage occurs on the main thread. r=seth, a=1.4+ 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
@@ -3392,16 +3392,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,