Bug 879475 - Make PBlob manually keep track of its manager r=jlebar
authorDavid Zbarsky <dzbarsky@gmail.com>
Tue, 16 Jul 2013 13:07:09 -0700
changeset 138754 e482a2e5d3b4e70a4f5c906fbec229a34b55f863
parent 138753 a2cdd84e44244a64dec3557b6f3fcfed471d8cda
child 138755 f38845197c8b35941727c89c8de02d08c8b531d8
push idunknown
push userunknown
push dateunknown
reviewersjlebar
bugs879475
milestone25.0a1
Bug 879475 - Make PBlob manually keep track of its manager r=jlebar
dom/ipc/Blob.cpp
dom/ipc/Blob.h
dom/ipc/ContentChild.cpp
dom/ipc/ContentParent.cpp
--- a/dom/ipc/Blob.cpp
+++ b/dom/ipc/Blob.cpp
@@ -835,17 +835,17 @@ private:
 
       NormalBlobConstructorParams normalParams;
       normalParams.contentType() = mContentType;
       normalParams.length() = mLength;
 
       typename ActorType::ConstructorParamsType params;
       ActorType::BaseType::SetBlobConstructorParams(params, normalParams);
 
-      ActorType* newActor = ActorType::Create(params);
+      ActorType* newActor = ActorType::Create(mActor->Manager(), params);
       MOZ_ASSERT(newActor);
 
       SlicedBlobConstructorParams slicedParams;
       slicedParams.contentType() = mContentType;
       slicedParams.begin() = mStart;
       slicedParams.end() = mStart + mLength;
       SetBlobOnParams(mActor, slicedParams);
 
@@ -1006,32 +1006,37 @@ RemoteBlob<Child>::GetInternalStream(nsI
     return NS_ERROR_UNEXPECTED;
   }
 
   nsRefPtr<StreamHelper> helper = new StreamHelper(mActor, this);
   return helper->GetStream(aStream);
 }
 
 template <ActorFlavorEnum ActorFlavor>
-Blob<ActorFlavor>::Blob(nsIDOMBlob* aBlob)
-: mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true), mBlobIsFile(false)
+Blob<ActorFlavor>::Blob(ContentManager* aManager, nsIDOMBlob* aBlob)
+: mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true)
+, mBlobIsFile(false), mManager(aManager)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(aBlob);
+  MOZ_ASSERT(aManager);
   aBlob->AddRef();
 
   nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
   mBlobIsFile = !!file;
 }
 
 template <ActorFlavorEnum ActorFlavor>
-Blob<ActorFlavor>::Blob(const ConstructorParamsType& aParams)
-: mBlob(nullptr), mRemoteBlob(nullptr), mOwnsBlob(false), mBlobIsFile(false)
+Blob<ActorFlavor>::Blob(ContentManager* aManager,
+                        const ConstructorParamsType& aParams)
+: mBlob(nullptr), mRemoteBlob(nullptr), mOwnsBlob(false)
+, mBlobIsFile(false), mManager(aManager)
 {
   MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aManager);
 
   ChildBlobConstructorParams::Type paramType =
     BaseType::GetBlobConstructorParams(aParams).type();
 
   mBlobIsFile =
     paramType == ChildBlobConstructorParams::TFileBlobConstructorParams ||
     paramType == ChildBlobConstructorParams::TMysteryBlobConstructorParams;
 
@@ -1043,43 +1048,44 @@ Blob<ActorFlavor>::Blob(const Constructo
   remoteBlob.forget(&mRemoteBlob);
 
   mBlob = mRemoteBlob;
   mOwnsBlob = true;
 }
 
 template <ActorFlavorEnum ActorFlavor>
 Blob<ActorFlavor>*
-Blob<ActorFlavor>::Create(const ConstructorParamsType& aParams)
+Blob<ActorFlavor>::Create(ContentManager* aManager,
+                          const ConstructorParamsType& aParams)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   const ChildBlobConstructorParams& blobParams =
     BaseType::GetBlobConstructorParams(aParams);
 
   switch (blobParams.type()) {
     case ChildBlobConstructorParams::TNormalBlobConstructorParams:
     case ChildBlobConstructorParams::TFileBlobConstructorParams:
     case ChildBlobConstructorParams::TMysteryBlobConstructorParams:
-      return new Blob<ActorFlavor>(aParams);
+      return new Blob<ActorFlavor>(aManager, aParams);
 
     case ChildBlobConstructorParams::TSlicedBlobConstructorParams: {
       const SlicedBlobConstructorParams& params =
         blobParams.get_SlicedBlobConstructorParams();
 
       nsCOMPtr<nsIDOMBlob> source = GetBlobFromParams<ActorFlavor>(params);
       MOZ_ASSERT(source);
 
       nsCOMPtr<nsIDOMBlob> slice;
       nsresult rv =
         source->Slice(params.begin(), params.end(), params.contentType(), 3,
                       getter_AddRefs(slice));
       NS_ENSURE_SUCCESS(rv, nullptr);
 
-      return new Blob<ActorFlavor>(slice);
+      return new Blob<ActorFlavor>(aManager, slice);
     }
 
     default:
       MOZ_CRASH("Unknown params!");
   }
 
   return nullptr;
 }
--- a/dom/ipc/Blob.h
+++ b/dom/ipc/Blob.h
@@ -157,16 +157,17 @@ template <ActorFlavorEnum>
 class RemoteBlob;
 
 template <ActorFlavorEnum ActorFlavor>
 class Blob : public BlobTraits<ActorFlavor>::BaseType
 {
   friend class RemoteBlob<ActorFlavor>;
 
 public:
+  typedef typename BlobTraits<ActorFlavor>::ConcreteContentManagerType ContentManager;
   typedef typename BlobTraits<ActorFlavor>::ProtocolType ProtocolType;
   typedef typename BlobTraits<ActorFlavor>::StreamType StreamType;
   typedef typename BlobTraits<ActorFlavor>::ConstructorParamsType
           ConstructorParamsType;
   typedef typename BlobTraits<ActorFlavor>::OtherSideConstructorParamsType
           OtherSideConstructorParamsType;
   typedef typename BlobTraits<ActorFlavor>::BaseType BaseType;
   typedef RemoteBlob<ActorFlavor> RemoteBlobType;
@@ -178,62 +179,69 @@ protected:
   nsIDOMBlob* mBlob;
   RemoteBlobType* mRemoteBlob;
   bool mOwnsBlob;
   bool mBlobIsFile;
 
 public:
   // This create function is called on the sending side.
   static Blob*
-  Create(nsIDOMBlob* aBlob)
+  Create(ContentManager* aManager, nsIDOMBlob* aBlob)
   {
-    return new Blob(aBlob);
+    return new Blob(aManager, aBlob);
   }
 
   // This create function is called on the receiving side.
   static Blob*
-  Create(const ConstructorParamsType& aParams);
+  Create(ContentManager* aManager, const ConstructorParamsType& aParams);
 
   // Get the blob associated with this actor. This may always be called on the
   // sending side. It may also be called on the receiving side unless this is a
   // "mystery" blob that has not yet received a SetMysteryBlobInfo() call.
   already_AddRefed<nsIDOMBlob>
   GetBlob();
 
   // Use this for files.
   bool
   SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
                      uint64_t aLength, uint64_t aLastModifiedDate);
 
   // Use this for non-file blobs.
   bool
   SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
 
+  ContentManager* Manager()
+  {
+    return mManager;
+  }
+
 private:
   // This constructor is called on the sending side.
-  Blob(nsIDOMBlob* aBlob);
+  Blob(ContentManager* aManager, nsIDOMBlob* aBlob);
 
   // This constructor is called on the receiving side.
-  Blob(const ConstructorParamsType& aParams);
+  Blob(ContentManager* aManager, const ConstructorParamsType& aParams);
 
   static already_AddRefed<RemoteBlobType>
   CreateRemoteBlob(const ConstructorParamsType& aParams);
 
   void
   NoteDyingRemoteBlob();
 
   // These methods are only called by the IPDL message machinery.
   virtual void
   ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
 
   virtual bool
   RecvResolveMystery(const ResolveMysteryParams& aParams) MOZ_OVERRIDE;
 
   virtual bool
   RecvPBlobStreamConstructor(StreamType* aActor) MOZ_OVERRIDE;
+
+  nsRefPtr<ContentManager> mManager;
 };
 
 } // namespace ipc
 
 typedef mozilla::dom::ipc::Blob<mozilla::dom::ipc::Child> BlobChild;
 typedef mozilla::dom::ipc::Blob<mozilla::dom::ipc::Parent> BlobParent;
 
 } // namespace dom
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -631,17 +631,17 @@ ContentChild::DeallocPBrowserChild(PBrow
     TabChild* child = static_cast<TabChild*>(iframe);
     NS_RELEASE(child);
     return true;
 }
 
 PBlobChild*
 ContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
 {
-  return BlobChild::Create(aParams);
+  return BlobChild::Create(this, aParams);
 }
 
 bool
 ContentChild::DeallocPBlobChild(PBlobChild* aActor)
 {
   delete aActor;
   return true;
 }
@@ -718,17 +718,17 @@ ContentChild::GetOrCreateActorForBlob(ns
     } else {
       NormalBlobConstructorParams blobParams;
       blobParams.contentType() = contentType;
       blobParams.length() = length;
       params.blobParams() = blobParams;
     }
     }
 
-  BlobChild* actor = BlobChild::Create(aBlob);
+  BlobChild* actor = BlobChild::Create(this, aBlob);
   NS_ENSURE_TRUE(actor, nullptr);
 
   if (!SendPBlobConstructor(actor, params)) {
         return nullptr;
       }
 
   return actor;
 }
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1687,17 +1687,17 @@ ContentParent::DeallocPDeviceStorageRequ
   DeviceStorageRequestParent *parent = static_cast<DeviceStorageRequestParent*>(doomed);
   NS_RELEASE(parent);
   return true;
 }
 
 PBlobParent*
 ContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
 {
-  return BlobParent::Create(aParams);
+  return BlobParent::Create(this, aParams);
 }
 
 bool
 ContentParent::DeallocPBlobParent(PBlobParent* aActor)
 {
   delete aActor;
   return true;
 }
@@ -1767,17 +1767,17 @@ ContentParent::GetOrCreateActorForBlob(n
     } else {
       NormalBlobConstructorParams blobParams;
       blobParams.contentType() = contentType;
       blobParams.length() = length;
       params = blobParams;
     }
       }
 
-  BlobParent* actor = BlobParent::Create(aBlob);
+  BlobParent* actor = BlobParent::Create(this, aBlob);
   NS_ENSURE_TRUE(actor, nullptr);
 
   if (!SendPBlobConstructor(actor, params)) {
     return nullptr;
   }
 
   return actor;
 }