Bug 516334: Track image decode notifications to send correct notifications to late-coming consumers (Tp4 orange fix). r=joe
authorBobby Holley <bobbyholley@gmail.com>
Mon, 14 Dec 2009 10:35:47 +0000
changeset 35718 44c392db667242eaa8d9279583cda6d62e65cfd9
parent 35717 82a6f0031d9f7568014a4430c24f277a81d1d0a2
child 35719 b35ebf2606ed51ae72532bddcea4648cdcd5943a
push id10691
push userjkew@mozilla.com
push dateMon, 14 Dec 2009 10:39:18 +0000
treeherdermozilla-central@44c392db6672 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjoe
bugs516334
milestone1.9.3a1pre
Bug 516334: Track image decode notifications to send correct notifications to late-coming consumers (Tp4 orange fix). r=joe
modules/libpr0n/src/imgRequest.cpp
modules/libpr0n/src/imgRequest.h
--- a/modules/libpr0n/src/imgRequest.cpp
+++ b/modules/libpr0n/src/imgRequest.cpp
@@ -185,21 +185,25 @@ nsresult imgRequest::RemoveProxy(imgRequ
 
   /* Check mState below before we potentially call Cancel() below. Since
      Cancel() may result in OnStopRequest being called back before Cancel()
      returns, leaving mState in a different state then the one it was in at
      this point.
    */
 
   if (aNotify) {
+    // The "real" OnStopDecode - fix this with bug 505385.
+    if (!(mState & stateDecodeStopped)) {
+      proxy->OnStopContainer(mImage);
+    }
+
     // make sure that observer gets an OnStopDecode message sent to it
     if (!(mState & stateRequestStopped)) {
       proxy->OnStopDecode(aStatus, nsnull);
     }
-
   }
 
   // make sure that observer gets an OnStopRequest message sent to it
   if (!(mState & stateRequestStopped)) {
     proxy->OnStopRequest(nsnull, nsnull, NS_BINDING_ABORTED, PR_TRUE);
   }
 
   if (mImage && !HaveProxyWithObserver(nsnull)) {
@@ -290,18 +294,21 @@ nsresult imgRequest::NotifyProxyListener
   }
 
   if (mImage && !HaveProxyWithObserver(proxy) && proxy->HasObserver()) {
     LOG_MSG(gImgLog, "imgRequest::NotifyProxyListener", "resetting animation");
 
     mImage->ResetAnimation();
   }
 
+  // The "real" OnStopDecode - Fix this with bug 505385.
+  if (mState & stateDecodeStopped)
+    proxy->OnStopContainer(mImage);
+
   if (mState & stateRequestStopped) {
-    proxy->OnStopContainer(mImage);
     proxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nsnull);
     proxy->OnStopRequest(nsnull, nsnull,
                          GetResultFromImageStatus(mImageStatus),
                          mHadLastPart);
   }
 
   return NS_OK;
 }
@@ -646,16 +653,20 @@ NS_IMETHODIMP imgRequest::OnStopFrame(im
 }
 
 /* void onStopContainer (in imgIRequest request, in imgIContainer image); */
 NS_IMETHODIMP imgRequest::OnStopContainer(imgIRequest *request,
                                           imgIContainer *image)
 {
   LOG_SCOPE(gImgLog, "imgRequest::OnStopContainer");
 
+  // XXXbholley - This should be moved into OnStopDecode when we fix bug
+  // 505385.
+  mState |= stateDecodeStopped;
+
   nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
   while (iter.HasMore()) {
     iter.GetNext()->OnStopContainer(image);
   }
 
   return NS_OK;
 }
 
@@ -695,17 +706,17 @@ NS_IMETHODIMP imgRequest::OnStopRequest(
   NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStopRequest");
   return NS_OK;
 }
 
 /* void onDiscard (in imgIRequest request); */
 NS_IMETHODIMP imgRequest::OnDiscard(imgIRequest *aRequest)
 {
   // Clear the state bits we no longer deserve.
-  PRUint32 stateBitsToClear = stateDecodeStarted;
+  PRUint32 stateBitsToClear = stateDecodeStarted | stateDecodeStopped;
   mState &= ~stateBitsToClear;
 
   // Clear the status bits we no longer deserve.
   PRUint32 statusBitsToClear = imgIRequest::STATUS_FRAME_COMPLETE
                                | imgIRequest::STATUS_DECODE_COMPLETE;
   mImageStatus &= ~statusBitsToClear;
 
   // Update the cache entry size, since we just got rid of frame data
@@ -745,16 +756,17 @@ NS_IMETHODIMP imgRequest::OnStartRequest
     mImage->NewSourceData();
 
     // Clear any status and state bits indicating load/decode
     mImageStatus &= ~imgIRequest::STATUS_LOAD_PARTIAL;
     mImageStatus &= ~imgIRequest::STATUS_LOAD_COMPLETE;
     mImageStatus &= ~imgIRequest::STATUS_FRAME_COMPLETE;
     mState &= ~stateRequestStarted;
     mState &= ~stateDecodeStarted;
+    mState &= ~stateDecodeStopped;
     mState &= ~stateRequestStopped;
   }
 
   /*
    * If mRequest is null here, then we need to set it so that we'll be able to
    * cancel it if our Cancel() method is called.  Note that this can only
    * happen for multipart channels.  We could simply not null out mRequest for
    * non-last parts, if GetIsLastPart() were reliable, but it's not.  See
--- a/modules/libpr0n/src/imgRequest.h
+++ b/modules/libpr0n/src/imgRequest.h
@@ -66,16 +66,17 @@ class imgCacheValidator;
 
 class imgRequestProxy;
 class imgCacheEntry;
 
 enum {
   stateRequestStarted    = PR_BIT(0),
   stateHasSize           = PR_BIT(1),
   stateDecodeStarted     = PR_BIT(2),
+  stateDecodeStopped     = PR_BIT(3),
   stateRequestStopped    = PR_BIT(4)
 };
 
 class imgRequest : public imgIDecoderObserver,
                    public nsIStreamListener,
                    public nsSupportsWeakReference,
                    public nsIChannelEventSink,
                    public nsIInterfaceRequestor