Bug 1308289 - Hold strong reference to VectorImage when dispatching ProgressTracker::SyncNotifyProgress. r=tnikkel
authorAndrew Osmond <aosmond@mozilla.com>
Thu, 13 Oct 2016 08:35:55 -0400
changeset 318379 956f4eff32d2ee80ae9c4ca9f58e2ca2f30a352f
parent 318378 4a0bc8102076724200062e131775a2aad00fdcf2
child 318380 5bc34a1ebba2718a3516ab95207be13048c62d8f
push id82902
push useraosmond@gmail.com
push dateTue, 18 Oct 2016 11:29:01 +0000
treeherdermozilla-inbound@956f4eff32d2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1308289
milestone52.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 1308289 - Hold strong reference to VectorImage when dispatching ProgressTracker::SyncNotifyProgress. r=tnikkel
image/VectorImage.cpp
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -148,17 +148,17 @@ private:
 
 public:
   void EndLoad(nsIDocument* aDocument) override
   {
     MOZ_ASSERT(aDocument == mDocument, "Got EndLoad for wrong document?");
 
     // OnSVGDocumentParsed will release our owner's reference to us, so ensure
     // we stick around long enough to complete our work.
-    RefPtr<SVGParseCompleteListener> kungFuDeathGroup(this);
+    RefPtr<SVGParseCompleteListener> kungFuDeathGrip(this);
 
     mImage->OnSVGDocumentParsed();
   }
 
   void Cancel()
   {
     MOZ_ASSERT(mDocument, "Duplicate call to Cancel");
     if (mDocument) {
@@ -207,17 +207,17 @@ private:
 
 public:
   NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent) override
   {
     MOZ_ASSERT(mDocument, "Need an SVG document. Received multiple events?");
 
     // OnSVGDocumentLoaded/OnSVGDocumentError will release our owner's reference
     // to us, so ensure we stick around long enough to complete our work.
-    RefPtr<SVGLoadEventListener> kungFuDeathGroup(this);
+    RefPtr<SVGLoadEventListener> kungFuDeathGrip(this);
 
     nsAutoString eventType;
     aEvent->GetType(eventType);
     MOZ_ASSERT(eventType.EqualsLiteral("MozSVGAsImageDocumentLoad")  ||
                eventType.EqualsLiteral("SVGAbort")                   ||
                eventType.EqualsLiteral("SVGError"),
                "Received unexpected event");
 
@@ -531,18 +531,18 @@ VectorImage::RequestRefresh(const TimeSt
     tracker->TriggerPendingAnimationsOnNextTick(aTime);
   }
 
   EvaluateAnimation();
 
   mSVGDocumentWrapper->TickRefreshDriver();
 
   if (mHasPendingInvalidation) {
+    mHasPendingInvalidation = false;
     SendInvalidationNotifications();
-    mHasPendingInvalidation = false;
   }
 }
 
 void
 VectorImage::SendInvalidationNotifications()
 {
   // Animated images don't send out invalidation notifications as soon as
   // they're generated. Instead, InvalidateObserversOnNextRefreshDriverTick
@@ -1135,16 +1135,20 @@ VectorImage::OnStartRequest(nsIRequest* 
   mSVGDocumentWrapper = new SVGDocumentWrapper();
   nsresult rv = mSVGDocumentWrapper->OnStartRequest(aRequest, aCtxt);
   if (NS_FAILED(rv)) {
     mSVGDocumentWrapper = nullptr;
     mError = true;
     return rv;
   }
 
+  // ProgressTracker::SyncNotifyProgress may release us, so ensure we
+  // stick around long enough to complete our work.
+  RefPtr<VectorImage> kungFuDeathGrip(this);
+
   // Block page load until the document's ready.  (We unblock it in
   // OnSVGDocumentLoaded or OnSVGDocumentError.)
   if (mProgressTracker) {
     mProgressTracker->SyncNotifyProgress(FLAG_ONLOAD_BLOCKED);
   }
 
   // Create a listener to wait until the SVG document is fully loaded, which
   // will signal that this image is ready to render. Certain error conditions
@@ -1215,16 +1219,20 @@ VectorImage::OnSVGDocumentLoaded()
   mSVGDocumentWrapper->FlushLayout();
 
   mIsFullyLoaded = true;
   mHaveAnimations = mSVGDocumentWrapper->IsAnimated();
 
   // Start listening to our image for rendering updates.
   mRenderingObserver = new SVGRootRenderingObserver(mSVGDocumentWrapper, this);
 
+  // ProgressTracker::SyncNotifyProgress may release us, so ensure we
+  // stick around long enough to complete our work.
+  RefPtr<VectorImage> kungFuDeathGrip(this);
+
   // Tell *our* observers that we're done loading.
   if (mProgressTracker) {
     Progress progress = FLAG_SIZE_AVAILABLE |
                         FLAG_HAS_TRANSPARENCY |
                         FLAG_FRAME_COMPLETE |
                         FLAG_DECODE_COMPLETE |
                         FLAG_ONLOAD_UNBLOCKED;