Bug 505385 - Part 10: Remove GetConsumers from imgStatusTracker by delegating all remaining notification operations from imgRequest to the status tracker. r=joe
authorJosh Matthews <josh@joshmatthews.net>
Fri, 12 Oct 2012 12:11:21 -0400
changeset 110234 423503422b5171d0f71e0da7ca17688c76733230
parent 110233 c401bda70ef9207e851c94d9cf87f2dd4a140166
child 110235 a913c8c0de54309d68e6b8f99fbc421ccbf9a0f7
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersjoe
bugs505385
milestone19.0a1
Bug 505385 - Part 10: Remove GetConsumers from imgStatusTracker by delegating all remaining notification operations from imgRequest to the status tracker. r=joe
image/src/imgRequest.cpp
image/src/imgStatusTracker.cpp
image/src/imgStatusTracker.h
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -512,28 +512,22 @@ NS_IMETHODIMP imgRequest::OnStartRequest
   if (!mRequest) {
     NS_ASSERTION(mpchan,
                  "We should have an mRequest here unless we're multipart");
     nsCOMPtr<nsIChannel> chan;
     mpchan->GetBaseChannel(getter_AddRefs(chan));
     mRequest = chan;
   }
 
-  imgStatusTracker& statusTracker = GetStatusTracker();
-  statusTracker.RecordStartRequest();
+  GetStatusTracker().OnStartRequest();
 
   nsCOMPtr<nsIChannel> channel(do_QueryInterface(aRequest));
   if (channel)
     channel->GetSecurityInfo(getter_AddRefs(mSecurityInfo));
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(GetStatusTracker().GetConsumers());
-  while (iter.HasMore()) {
-    statusTracker.SendStartRequest(iter.GetNext());
-  }
-
   /* Get our principal */
   nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
   if (chan) {
     nsCOMPtr<nsIScriptSecurityManager> secMan =
       do_GetService("@mozilla.org/scriptsecuritymanager;1");
     if (secMan) {
       nsresult rv = secMan->GetChannelPrincipal(chan,
                                                 getter_AddRefs(mPrincipal));
@@ -611,21 +605,17 @@ NS_IMETHODIMP imgRequest::OnStopRequest(
     // loading compressed source data, which is part of our size calculus.
     UpdateCacheEntrySize();
   }
   else {
     // stops animations, removes from cache
     this->Cancel(status);
   }
 
-  /* notify the kids */
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator srIter(GetStatusTracker().GetConsumers());
-  while (srIter.HasMore()) {
-    statusTracker.SendStopRequest(srIter.GetNext(), lastPart, status);
-  }
+  GetStatusTracker().OnStopRequest(lastPart, status);
 
   mTimedChannel = nullptr;
   return NS_OK;
 }
 
 struct mimetype_closure
 {
   imgRequest* request;
@@ -716,21 +706,17 @@ imgRequest::OnDataAvailable(nsIRequest *
       /* now we have mimetype, so we can infer the image type that we want */
       if (mContentType.EqualsLiteral(SVG_MIMETYPE)) {
         mImage = new VectorImage(mStatusTracker.forget());
       } else {
         mImage = new RasterImage(mStatusTracker.forget());
       }
       mImage->SetInnerWindowID(mInnerWindowId);
 
-      // Notify any imgRequestProxys that are observing us that we have an Image.
-    nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(GetStatusTracker().GetConsumers());
-      while (iter.HasMore()) {
-        iter.GetNext()->SetHasImage();
-      }
+      GetStatusTracker().OnDataAvailable();
 
       /* set our mimetype as a property */
       nsCOMPtr<nsISupportsCString> contentType(do_CreateInstance("@mozilla.org/supports-cstring;1"));
       if (contentType) {
         contentType->SetData(mContentType);
         mProperties->Set("type", contentType);
       }
 
--- a/image/src/imgStatusTracker.cpp
+++ b/image/src/imgStatusTracker.cpp
@@ -35,17 +35,17 @@ NS_IMETHODIMP imgStatusTrackerObserver::
                                                      const nsIntRect *dirtyRect)
 {
   LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::FrameChanged");
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "FrameChanged callback before we've created our image");
 
   mTracker->RecordFrameChanged(container, dirtyRect);
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendFrameChanged(iter.GetNext(), container, dirtyRect);
   }
 
   return NS_OK;
 }
 
 /** imgIDecoderObserver methods **/
@@ -55,28 +55,28 @@ NS_IMETHODIMP imgStatusTrackerObserver::
 {
   LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStartDecode");
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnStartDecode callback before we've created our image");
 
 
   mTracker->RecordStartDecode();
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendStartDecode(iter.GetNext());
   }
 
   if (!mTracker->GetRequest()->GetMultipart()) {
     MOZ_ASSERT(!mTracker->mBlockingOnload);
     mTracker->mBlockingOnload = true;
 
     mTracker->RecordBlockOnload();
 
-    nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+    nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
     while (iter.HasMore()) {
       mTracker->SendBlockOnload(iter.GetNext());
     }
   }
 
   /* In the case of streaming jpegs, it is possible to get multiple OnStartDecodes which
      indicates the beginning of a new decode.
      The cache entry's size therefore needs to be reset to 0 here.  If we do not do this,
@@ -102,17 +102,17 @@ NS_IMETHODIMP imgStatusTrackerObserver::
   if (!image) return NS_ERROR_UNEXPECTED;
 
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnStartContainer callback before we've created our image");
   NS_ABORT_IF_FALSE(image == mTracker->GetImage(),
                     "OnStartContainer callback from an image we don't own");
   mTracker->RecordStartContainer(image);
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendStartContainer(iter.GetNext(), image);
   }
 
   return NS_OK;
 }
 
 /* void onStartFrame (in imgIRequest request, in unsigned long frame); */
@@ -120,17 +120,17 @@ NS_IMETHODIMP imgStatusTrackerObserver::
                                        uint32_t frame)
 {
   LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStartFrame");
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnStartFrame callback before we've created our image");
 
   mTracker->RecordStartFrame(frame);
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendStartFrame(iter.GetNext(), frame);
   }
 
   return NS_OK;
 }
 
 /* [noscript] void onDataAvailable (in imgIRequest request, in boolean aCurrentFrame, [const] in nsIntRect rect); */
@@ -139,17 +139,17 @@ NS_IMETHODIMP imgStatusTrackerObserver::
                                           const nsIntRect * rect)
 {
   LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnDataAvailable");
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnDataAvailable callback before we've created our image");
 
   mTracker->RecordDataAvailable(aCurrentFrame, rect);
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendDataAvailable(iter.GetNext(), aCurrentFrame, rect);
   }
 
   return NS_OK;
 }
 
 /* void onStopFrame (in imgIRequest request, in unsigned long frame); */
@@ -157,17 +157,17 @@ NS_IMETHODIMP imgStatusTrackerObserver::
                                       uint32_t frame)
 {
   LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStopFrame");
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnStopFrame callback before we've created our image");
 
   mTracker->RecordStopFrame(frame);
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendStopFrame(iter.GetNext(), frame);
   }
 
   mTracker->MaybeUnblockOnload();
 
   return NS_OK;
 }
@@ -177,17 +177,17 @@ NS_IMETHODIMP imgStatusTrackerObserver::
                                           imgIContainer *image)
 {
   LOG_SCOPE(gImgLog, "imgStatusTrackerObserver::OnStopContainer");
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnDataContainer callback before we've created our image");
 
   mTracker->RecordStopContainer(image);
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendStopContainer(iter.GetNext(), image);
   }
 
   // This is really hacky. We need to handle the case where we start decoding,
   // block onload, but then hit an error before we get to our first frame. In
   // theory we would just hook in at OnStopDecode, but OnStopDecode is broken
   // until we fix bug 505385. OnStopContainer is actually going away at that
@@ -208,17 +208,17 @@ NS_IMETHODIMP imgStatusTrackerObserver::
                     "OnDataDecode callback before we've created our image");
 
   // We finished the decode, and thus have the decoded frames. Update the cache
   // entry size to take this into account.
   mTracker->GetRequest()->UpdateCacheEntrySize();
 
   mTracker->RecordStopDecode(aStatus, aStatusArg);
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendStopDecode(iter.GetNext(), aStatus, aStatusArg);
   }
 
   if (NS_FAILED(aStatus)) {
     // Some kind of problem has happened with image decoding.
     // Report the URI to net:failed-to-process-uri-conent observers.
 
@@ -259,31 +259,31 @@ NS_IMETHODIMP imgStatusTrackerObserver::
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnDiscard callback before we've created our image");
 
   mTracker->RecordDiscard();
 
   // Update the cache entry size, since we just got rid of frame data
   mTracker->GetRequest()->UpdateCacheEntrySize();
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendDiscard(iter.GetNext());
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP imgStatusTrackerObserver::OnImageIsAnimated(imgIRequest *aRequest)
 {
   NS_ABORT_IF_FALSE(mTracker->GetImage(),
                     "OnImageIsAnimated callback before we've created our image");
   mTracker->RecordImageIsAnimated();
 
-  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->GetConsumers());
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mTracker->mConsumers);
   while (iter.HasMore()) {
     mTracker->SendImageIsAnimated(iter.GetNext());
   }
 
   return NS_OK;
 }
 
 // imgStatusTracker methods
@@ -787,16 +787,26 @@ imgStatusTracker::RecordStartRequest()
 void
 imgStatusTracker::SendStartRequest(imgRequestProxy* aProxy)
 {
   if (!aProxy->NotificationsDeferred())
     aProxy->OnStartRequest();
 }
 
 void
+imgStatusTracker::OnStartRequest()
+{
+  RecordStartRequest();
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mConsumers);
+  while (iter.HasMore()) {
+    SendStartRequest(iter.GetNext());
+  }
+}
+
+void
 imgStatusTracker::RecordStopRequest(bool aLastPart, nsresult aStatus)
 {
   mHadLastPart = aLastPart;
   mState |= stateRequestStopped;
 
   // If we were successful in loading, note that the image is complete.
   if (NS_SUCCEEDED(aStatus))
     mImageStatus |= imgIRequest::STATUS_LOAD_COMPLETE;
@@ -809,16 +819,37 @@ imgStatusTracker::SendStopRequest(imgReq
   // OnStopDecode is called with OnStopRequest.
   if (!aProxy->NotificationsDeferred()) {
     aProxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nullptr);
     aProxy->OnStopRequest(aLastPart);
   }
 }
 
 void
+imgStatusTracker::OnStopRequest(bool aLastPart, nsresult aStatus)
+{
+  RecordStopRequest(aLastPart, aStatus);
+  /* notify the kids */
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator srIter(mConsumers);
+  while (srIter.HasMore()) {
+    SendStopRequest(srIter.GetNext(), aLastPart, aStatus);
+  }
+}
+
+void
+imgStatusTracker::OnDataAvailable()
+{
+  // Notify any imgRequestProxys that are observing us that we have an Image.
+  nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mConsumers);
+  while (iter.HasMore()) {
+    iter.GetNext()->SetHasImage();
+  }
+}
+
+void
 imgStatusTracker::RecordBlockOnload()
 {
   MOZ_ASSERT(!(mState & stateBlockingOnload));
   mState |= stateBlockingOnload;
 }
 
 void
 imgStatusTracker::SendBlockOnload(imgRequestProxy* aProxy)
--- a/image/src/imgStatusTracker.h
+++ b/image/src/imgStatusTracker.h
@@ -119,19 +119,16 @@ public:
 
   // This is intentionally non-general because its sole purpose is to support an
   // some obscure network priority logic in imgRequest. That stuff could probably
   // be improved, but it's too scary to mess with at the moment.
   bool FirstConsumerIs(imgRequestProxy* aConsumer) {
     return mConsumers.SafeElementAt(0, nullptr) == aConsumer;
   }
 
-  // Temporary hack that goes away in the next patch.
-  const nsTObserverArray<imgRequestProxy*>& GetConsumers() { return mConsumers; };
-
   void AdoptConsumers(imgStatusTracker* aTracker) { mConsumers = aTracker->mConsumers; }
 
   // Returns whether we are in the process of loading; that is, whether we have
   // not received OnStopRequest.
   bool IsLoading() const;
 
   // Get the current image status (as in imgIRequest).
   uint32_t GetImageStatus() const;
@@ -178,16 +175,20 @@ public:
                         const nsIntRect* aDirtyRect);
 
   /* non-virtual sort-of-nsIRequestObserver methods */
   void RecordStartRequest();
   void SendStartRequest(imgRequestProxy* aProxy);
   void RecordStopRequest(bool aLastPart, nsresult aStatus);
   void SendStopRequest(imgRequestProxy* aProxy, bool aLastPart, nsresult aStatus);
 
+  void OnStartRequest();
+  void OnDataAvailable();
+  void OnStopRequest(bool aLastPart, nsresult aStatus);
+
   /* non-virtual imgIOnloadBlocker methods */
   // NB: If UnblockOnload is sent, and then we are asked to replay the
   // notifications, we will not send a BlockOnload/UnblockOnload pair.  This
   // is different from all the other notifications.
   void RecordBlockOnload();
   void SendBlockOnload(imgRequestProxy* aProxy);
   void RecordUnblockOnload();
   void SendUnblockOnload(imgRequestProxy* aProxy);