Bug 505385 - Part 5: Expose pointers to the imgRequest and Image on imgStatusTracker. r=joe
authorBobby Holley <bobbyholley@gmail.com>
Fri, 12 Oct 2012 12:11:20 -0400
changeset 110229 3dce664cb6636aa13ff8adca3889f12433fe8360
parent 110228 f11329484155b73a14090ef2e5364c8e7393b290
child 110230 a8c623232db48ae088cf371f8883a545e9a3716e
push id93
push usernmatsakis@mozilla.com
push dateWed, 31 Oct 2012 21:26:57 +0000
reviewersjoe
bugs505385
milestone19.0a1
Bug 505385 - Part 5: Expose pointers to the imgRequest and Image on imgStatusTracker. r=joe This will help us decouple imgRequest and imgRequestProxy.
image/src/Image.cpp
image/src/imgRequest.cpp
image/src/imgStatusTracker.cpp
image/src/imgStatusTracker.h
--- a/image/src/Image.cpp
+++ b/image/src/Image.cpp
@@ -16,17 +16,17 @@ Image::Image(imgStatusTracker* aStatusTr
   mInitialized(false),
   mAnimating(false),
   mError(false)
 {
   if (aStatusTracker) {
     mStatusTracker = aStatusTracker;
     mStatusTracker->SetImage(this);
   } else {
-    mStatusTracker = new imgStatusTracker(this);
+    mStatusTracker = new imgStatusTracker(this, nullptr);
   }
 }
 
 uint32_t
 Image::SizeOfData()
 {
   if (mError)
     return 0;
--- a/image/src/imgRequest.cpp
+++ b/image/src/imgRequest.cpp
@@ -122,17 +122,17 @@ nsresult imgRequest::Init(nsIURI *aURI,
   NS_ABORT_IF_FALSE(!mImage, "Multiple calls to init");
   NS_ABORT_IF_FALSE(aURI, "No uri");
   NS_ABORT_IF_FALSE(aCurrentURI, "No current uri");
   NS_ABORT_IF_FALSE(aRequest, "No request");
   NS_ABORT_IF_FALSE(aChannel, "No channel");
 
   mProperties = do_CreateInstance("@mozilla.org/properties;1");
 
-  mStatusTracker = new imgStatusTracker(nullptr);
+  mStatusTracker = new imgStatusTracker(nullptr, this);
 
   mURI = aURI;
   mCurrentURI = aCurrentURI;
   mRequest = aRequest;
   mChannel = aChannel;
   mTimedChannel = do_QueryInterface(mChannel);
 
   mLoadingPrincipal = aLoadingPrincipal;
@@ -990,17 +990,17 @@ imgRequest::OnDataAvailable(nsIRequest *
     if (mContentType != newType || newType.EqualsLiteral(SVG_MIMETYPE)) {
       mContentType = newType;
 
       // If we've resniffed our MIME type and it changed, we need to create a
       // new status tracker to give to the image, because we don't have one of
       // our own any more.
       if (mResniffMimeType) {
         NS_ABORT_IF_FALSE(mIsMultiPartChannel, "Resniffing a non-multipart image");
-        imgStatusTracker* freshTracker = new imgStatusTracker(nullptr);
+        imgStatusTracker* freshTracker = new imgStatusTracker(nullptr, this);
         freshTracker->AdoptConsumers(mStatusTracker);
         mStatusTracker = freshTracker;
       }
 
       mResniffMimeType = false;
 
       /* now we have mimetype, so we can infer the image type that we want */
       if (mContentType.EqualsLiteral(SVG_MIMETYPE)) {
--- a/image/src/imgStatusTracker.cpp
+++ b/image/src/imgStatusTracker.cpp
@@ -23,25 +23,27 @@ GetResultFromImageStatus(uint32_t aStatu
 {
   if (aStatus & imgIRequest::STATUS_ERROR)
     return NS_IMAGELIB_ERROR_FAILURE;
   if (aStatus & imgIRequest::STATUS_LOAD_COMPLETE)
     return NS_IMAGELIB_SUCCESS_LOAD_FINISHED;
   return NS_OK;
 }
 
-imgStatusTracker::imgStatusTracker(Image* aImage)
+imgStatusTracker::imgStatusTracker(Image* aImage, imgRequest* aRequest)
   : mImage(aImage),
+    mRequest(aRequest),
     mState(0),
     mImageStatus(imgIRequest::STATUS_NONE),
     mHadLastPart(false)
 {}
 
 imgStatusTracker::imgStatusTracker(const imgStatusTracker& aOther)
   : mImage(aOther.mImage),
+    mRequest(aOther.mRequest),
     mState(aOther.mState),
     mImageStatus(aOther.mImageStatus),
     mHadLastPart(aOther.mHadLastPart)
     // Note: we explicitly don't copy mRequestRunnable, because it won't be
     // nulled out when the mRequestRunnable's Run function eventually gets
     // called.
 {}
 
--- a/image/src/imgStatusTracker.h
+++ b/image/src/imgStatusTracker.h
@@ -47,17 +47,17 @@ enum {
  */
 
 class imgStatusTracker
 {
 public:
   // aImage is the image that this status tracker will pass to the
   // imgRequestProxys in SyncNotify() and EmulateRequestFinished(), and must be
   // alive as long as this instance is, because we hold a weak reference to it.
-  imgStatusTracker(mozilla::image::Image* aImage);
+  imgStatusTracker(mozilla::image::Image* aImage, imgRequest* aRequest);
   imgStatusTracker(const imgStatusTracker& aOther);
 
   // Image-setter, for imgStatusTrackers created by imgRequest::Init, which
   // are created before their Image is created.  This method should only
   // be called once, and only on an imgStatusTracker that was initialized
   // without an image.
   void SetImage(mozilla::image::Image* aImage);
 
@@ -162,25 +162,30 @@ public:
   // 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);
 
+  // Weak pointer getters - no AddRefs.
+  inline mozilla::image::Image* GetImage() const { return mImage; };
+  inline imgRequest* GetRequest() const { return mRequest; };
+
 private:
   friend class imgStatusNotifyRunnable;
   friend class imgRequestNotifyRunnable;
 
   nsCOMPtr<nsIRunnable> mRequestRunnable;
 
-  // A weak pointer to the Image, because it owns us, and we
-  // can't create a cycle.
+  // Weak pointers to the image and request. The request owns the image, and
+  // the image (or the request, if there's no image) owns the status tracker.
   mozilla::image::Image* mImage;
+  imgRequest* mRequest;
   uint32_t mState;
   uint32_t mImageStatus;
   bool mHadLastPart;
 
   // List of proxies attached to the image. Each proxy represents a consumer
   // using the image.
   nsTObserverArray<imgRequestProxy*> mConsumers;
 };