Backout 1391e924e9ee (bug 806503) for mochitest-1 failures on a CLOSED TREE

This commit is contained in:
Ed Morley
2013-01-10 15:21:39 +00:00
parent d9ca60316b
commit 9d3687d13d
14 changed files with 195 additions and 812 deletions

View File

@@ -48,8 +48,6 @@ public:
virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >* virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
GetSubBlobs() const { return nullptr; } GetSubBlobs() const { return nullptr; }
virtual bool IsMemoryBacked() const { return false; }
NS_DECL_NSIDOMBLOB NS_DECL_NSIDOMBLOB
NS_DECL_NSIDOMFILE NS_DECL_NSIDOMFILE
NS_DECL_NSIXHRSENDABLE NS_DECL_NSIXHRSENDABLE
@@ -352,9 +350,8 @@ public:
nsDOMMemoryFile(void *aMemoryBuffer, nsDOMMemoryFile(void *aMemoryBuffer,
uint64_t aLength, uint64_t aLength,
const nsAString& aName, const nsAString& aName,
const nsAString& aContentType, const nsAString& aContentType)
uint64_t aModDate = UINT64_MAX) : nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
: nsDOMFile(aName, aContentType, aLength, aModDate),
mDataOwner(new DataOwner(aMemoryBuffer, aLength)) mDataOwner(new DataOwner(aMemoryBuffer, aLength))
{ {
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data"); NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
@@ -372,10 +369,6 @@ public:
NS_IMETHOD GetInternalStream(nsIInputStream**); NS_IMETHOD GetInternalStream(nsIInputStream**);
virtual bool IsMemoryBacked() const { return true; }
void* GetData() const { return mDataOwner->mData; }
uint64_t GetLength() const { return mDataOwner->mLength; }
protected: protected:
// Create slice // Create slice
nsDOMMemoryFile(const nsDOMMemoryFile* aOther, uint64_t aStart, nsDOMMemoryFile(const nsDOMMemoryFile* aOther, uint64_t aStart,

View File

@@ -145,7 +145,7 @@ nsDOMMultipartFile::CreateSlice(uint64_t aStart, uint64_t aLength,
nsDOMMultipartFile::NewFile(const nsAString& aName, nsISupports* *aNewObject) nsDOMMultipartFile::NewFile(const nsAString& aName, nsISupports* *aNewObject)
{ {
nsCOMPtr<nsISupports> file = nsCOMPtr<nsISupports> file =
do_QueryObject(new nsDOMMultipartFile(aName, EmptyString())); do_QueryObject(new nsDOMMultipartFile(aName));
file.forget(aNewObject); file.forget(aNewObject);
return NS_OK; return NS_OK;
} }
@@ -153,7 +153,7 @@ nsDOMMultipartFile::NewFile(const nsAString& aName, nsISupports* *aNewObject)
/* static */ nsresult /* static */ nsresult
nsDOMMultipartFile::NewBlob(nsISupports* *aNewObject) nsDOMMultipartFile::NewBlob(nsISupports* *aNewObject)
{ {
nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMMultipartFile(EmptyString())); nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMMultipartFile());
file.forget(aNewObject); file.forget(aNewObject);
return NS_OK; return NS_OK;
} }

View File

@@ -16,7 +16,7 @@ class nsDOMMultipartFile : public nsDOMFile,
{ {
public: public:
// Create as a file // Create as a file
nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> >& aBlobs, nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
const nsAString& aName, const nsAString& aName,
const nsAString& aContentType) const nsAString& aContentType)
: nsDOMFile(aName, aContentType, UINT64_MAX), : nsDOMFile(aName, aContentType, UINT64_MAX),
@@ -33,15 +33,14 @@ public:
} }
// Create as a file to be later initialized // Create as a file to be later initialized
nsDOMMultipartFile(const nsAString& aName, nsDOMMultipartFile(const nsAString& aName)
const nsAString& aContentType) : nsDOMFile(aName, EmptyString(), UINT64_MAX)
: nsDOMFile(aName, aContentType, UINT64_MAX)
{ {
} }
// Create as a blob to be later initialized // Create as a blob to be later initialized
nsDOMMultipartFile(const nsAString& aContentType) nsDOMMultipartFile()
: nsDOMFile(aContentType, UINT64_MAX) : nsDOMFile(EmptyString(), UINT64_MAX)
{ {
} }
@@ -89,12 +88,6 @@ public:
virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >* virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
GetSubBlobs() const { return &mBlobs; } GetSubBlobs() const { return &mBlobs; }
void
AddBlob(nsIDOMBlob* aBlob)
{
mBlobs.AppendElement(aBlob);
}
protected: protected:
nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs; nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
}; };

View File

@@ -21,7 +21,6 @@
#include "mozilla/unused.h" #include "mozilla/unused.h"
#include "mozilla/ipc/InputStreamUtils.h" #include "mozilla/ipc/InputStreamUtils.h"
#include "nsDOMFile.h" #include "nsDOMFile.h"
#include "nsDOMBlobBuilder.h"
#include "nsThreadUtils.h" #include "nsThreadUtils.h"
#include "ContentChild.h" #include "ContentChild.h"
@@ -631,51 +630,17 @@ BlobTraits<Parent>::BaseType::NoteRunnableCompleted(
} }
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
class RemoteBlobBase : public nsIRemoteBlob class RemoteBlob : public nsDOMFile,
public nsIRemoteBlob
{ {
public: public:
typedef RemoteBlob<ActorFlavor> SelfType; typedef RemoteBlob<ActorFlavor> SelfType;
typedef Blob<ActorFlavor> ActorType; typedef Blob<ActorFlavor> ActorType;
typedef InputStreamActor<ActorFlavor> StreamActorType; typedef InputStreamActor<ActorFlavor> StreamActorType;
void
SetPBlob(void* aActor) MOZ_OVERRIDE
{
MOZ_ASSERT(!aActor || !mActor);
mActor = static_cast<ActorType*>(aActor);
}
virtual void*
GetPBlob() MOZ_OVERRIDE
{
return static_cast<typename ActorType::ProtocolType*>(mActor);
}
private: private:
ActorType* mActor; ActorType* mActor;
protected:
RemoteBlobBase()
: mActor(nullptr)
{ }
virtual
~RemoteBlobBase()
{
if (mActor) {
mActor->NoteDyingRemoteBlob();
}
}
ActorType* Actor() const { return mActor; }
};
template <ActorFlavorEnum ActorFlavor>
class RemoteBlob : public nsDOMFile,
public RemoteBlobBase<ActorFlavor>
{
typedef Blob<ActorFlavor> ActorType;
public:
class StreamHelper : public nsRunnable class StreamHelper : public nsRunnable
{ {
typedef Blob<ActorFlavor> ActorType; typedef Blob<ActorFlavor> ActorType;
@@ -792,7 +757,6 @@ public:
{ {
// This may be created on any thread. // This may be created on any thread.
MOZ_ASSERT(aActor); MOZ_ASSERT(aActor);
MOZ_ASSERT(aActor->HasManager());
} }
nsresult nsresult
@@ -859,11 +823,8 @@ public:
normalParams.contentType() = mContentType; normalParams.contentType() = mContentType;
normalParams.length() = mLength; normalParams.length() = mLength;
BlobConstructorNoMultipartParams params(normalParams); ActorType* newActor = ActorType::Create(normalParams);
ActorType* newActor = ActorType::Create(params);
MOZ_ASSERT(newActor); MOZ_ASSERT(newActor);
mActor->PropagateManager(newActor);
SlicedBlobConstructorParams slicedParams; SlicedBlobConstructorParams slicedParams;
slicedParams.contentType() = mContentType; slicedParams.contentType() = mContentType;
@@ -871,8 +832,7 @@ public:
slicedParams.end() = mStart + mLength; slicedParams.end() = mStart + mLength;
SetBlobOnParams(mActor, slicedParams); SetBlobOnParams(mActor, slicedParams);
BlobConstructorNoMultipartParams params2(slicedParams); if (mActor->Manager()->SendPBlobConstructor(newActor, slicedParams)) {
if (mActor->ConstructPBlobOnManager(newActor, params2)) {
mSlice = newActor->GetBlob(); mSlice = newActor->GetBlob();
} }
@@ -894,40 +854,54 @@ public:
RemoteBlob(const nsAString& aName, const nsAString& aContentType, RemoteBlob(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aModDate) uint64_t aLength, uint64_t aModDate)
: nsDOMFile(aName, aContentType, aLength, aModDate) : nsDOMFile(aName, aContentType, aLength, aModDate), mActor(nullptr)
{ {
mImmutable = true; mImmutable = true;
} }
RemoteBlob(const nsAString& aName, const nsAString& aContentType, RemoteBlob(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength) uint64_t aLength)
: nsDOMFile(aName, aContentType, aLength) : nsDOMFile(aName, aContentType, aLength), mActor(nullptr)
{ {
mImmutable = true; mImmutable = true;
} }
RemoteBlob(const nsAString& aContentType, uint64_t aLength) RemoteBlob(const nsAString& aContentType, uint64_t aLength)
: nsDOMFile(aContentType, aLength) : nsDOMFile(aContentType, aLength), mActor(nullptr)
{ {
mImmutable = true; mImmutable = true;
} }
RemoteBlob() RemoteBlob()
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX) : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
, mActor(nullptr)
{ {
mImmutable = true; mImmutable = true;
} }
virtual ~RemoteBlob()
{
if (mActor) {
mActor->NoteDyingRemoteBlob();
}
}
void
SetActor(ActorType* aActor)
{
MOZ_ASSERT(!aActor || !mActor);
mActor = aActor;
}
virtual already_AddRefed<nsIDOMBlob> virtual already_AddRefed<nsIDOMBlob>
CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType) CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType)
MOZ_OVERRIDE MOZ_OVERRIDE
{ {
ActorType* actor = RemoteBlobBase<ActorFlavor>::Actor(); if (!mActor) {
if (!actor) {
return nullptr; return nullptr;
} }
nsRefPtr<SliceHelper> helper = new SliceHelper(actor); nsRefPtr<SliceHelper> helper = new SliceHelper(mActor);
nsCOMPtr<nsIDOMBlob> slice; nsCOMPtr<nsIDOMBlob> slice;
nsresult rv = nsresult rv =
@@ -940,100 +914,18 @@ public:
NS_IMETHOD NS_IMETHOD
GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE GetInternalStream(nsIInputStream** aStream) MOZ_OVERRIDE
{ {
ActorType* actor = RemoteBlobBase<ActorFlavor>::Actor(); if (!mActor) {
if (!actor) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
nsRefPtr<StreamHelper> helper = new StreamHelper(actor, this); nsRefPtr<StreamHelper> helper = new StreamHelper(mActor, this);
return helper->GetStream(aStream); return helper->GetStream(aStream);
} }
NS_IMETHOD virtual void*
GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate) GetPBlob() MOZ_OVERRIDE
{ {
if (IsDateUnknown()) { return static_cast<typename ActorType::ProtocolType*>(mActor);
aLastModifiedDate->setNull();
} else {
JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
if (!date) {
return NS_ERROR_OUT_OF_MEMORY;
}
aLastModifiedDate->setObject(*date);
}
return NS_OK;
}
};
template <ActorFlavorEnum ActorFlavor>
class RemoteMemoryBlob : public nsDOMMemoryFile,
public RemoteBlobBase<ActorFlavor>
{
public:
NS_DECL_ISUPPORTS_INHERITED
RemoteMemoryBlob(void* aMemoryBuffer,
uint64_t aLength,
const nsAString& aName,
const nsAString& aContentType,
uint64_t aModDate)
: nsDOMMemoryFile(aMemoryBuffer, aLength, aName, aContentType, aModDate)
{
mImmutable = true;
}
RemoteMemoryBlob(void* aMemoryBuffer,
uint64_t aLength,
const nsAString& aName,
const nsAString& aContentType)
: nsDOMMemoryFile(aMemoryBuffer, aLength, aName, aContentType)
{
mImmutable = true;
}
RemoteMemoryBlob(void* aMemoryBuffer,
uint64_t aLength,
const nsAString& aContentType)
: nsDOMMemoryFile(aMemoryBuffer, aLength, EmptyString(), aContentType)
{
mImmutable = true;
}
NS_IMETHOD
GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
{
if (IsDateUnknown()) {
aLastModifiedDate->setNull();
} else {
JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
if (!date) {
return NS_ERROR_OUT_OF_MEMORY;
}
aLastModifiedDate->setObject(*date);
}
return NS_OK;
}
};
template <ActorFlavorEnum ActorFlavor>
class RemoteMultipartBlob : public nsDOMMultipartFile,
public RemoteBlobBase<ActorFlavor>
{
public:
NS_DECL_ISUPPORTS_INHERITED
RemoteMultipartBlob(const nsAString& aName,
const nsAString& aContentType)
: nsDOMMultipartFile(aName, aContentType)
{
mImmutable = true;
}
RemoteMultipartBlob(const nsAString& aName)
: nsDOMMultipartFile(aName)
{
mImmutable = true;
} }
NS_IMETHOD NS_IMETHOD
@@ -1054,9 +946,7 @@ public:
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
Blob<ActorFlavor>::Blob(nsIDOMBlob* aBlob) Blob<ActorFlavor>::Blob(nsIDOMBlob* aBlob)
: mBlob(aBlob), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr), : mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true), mBlobIsFile(false)
mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(false)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob); MOZ_ASSERT(aBlob);
@@ -1067,70 +957,44 @@ Blob<ActorFlavor>::Blob(nsIDOMBlob* aBlob)
} }
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
Blob<ActorFlavor>::Blob(nsRefPtr<RemoteBlobType>& aBlob, Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
bool aBlobIsFile) : mBlob(nullptr), mRemoteBlob(nullptr), mOwnsBlob(false), mBlobIsFile(false)
: mBlob(nullptr), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr),
mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(aBlobIsFile)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mBlob);
MOZ_ASSERT(!mRemoteBlob);
MOZ_ASSERT(aBlob);
if (NS_FAILED(aBlob->SetMutable(false))) { nsRefPtr<RemoteBlobType> remoteBlob;
MOZ_NOT_REACHED("Failed to make remote blob immutable!");
switch (aParams.type()) {
case BlobConstructorParams::TNormalBlobConstructorParams: {
const NormalBlobConstructorParams& params =
aParams.get_NormalBlobConstructorParams();
remoteBlob = new RemoteBlobType(params.contentType(), params.length());
break;
} }
aBlob->SetPBlob(this); case BlobConstructorParams::TFileBlobConstructorParams: {
aBlob.forget(&mRemoteBlob); const FileBlobConstructorParams& params =
aParams.get_FileBlobConstructorParams();
mBlob = mRemoteBlob; remoteBlob =
new RemoteBlobType(params.name(), params.contentType(),
params.length(), params.modDate());
mBlobIsFile = true;
break;
} }
template <ActorFlavorEnum ActorFlavor> case BlobConstructorParams::TMysteryBlobConstructorParams: {
Blob<ActorFlavor>::Blob(nsRefPtr<RemoteMemoryBlobType>& aBlob, remoteBlob = new RemoteBlobType();
bool aBlobIsFile) mBlobIsFile = true;
: mBlob(nullptr), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr), break;
mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(aBlobIsFile)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mBlob);
MOZ_ASSERT(!mRemoteMemoryBlob);
MOZ_ASSERT(aBlob);
if (NS_FAILED(aBlob->SetMutable(false))) {
MOZ_NOT_REACHED("Failed to make remote blob immutable!");
} }
aBlob->SetPBlob(this); default:
aBlob.forget(&mRemoteMemoryBlob); MOZ_NOT_REACHED("Unknown params!");
mBlob = mRemoteMemoryBlob;
} }
template <ActorFlavorEnum ActorFlavor> MOZ_ASSERT(remoteBlob);
Blob<ActorFlavor>::Blob(nsRefPtr<RemoteMultipartBlobType>& aBlob,
bool aBlobIsFile)
: mBlob(nullptr), mRemoteBlob(nullptr), mRemoteMemoryBlob(nullptr),
mRemoteMultipartBlob(nullptr), mContentManager(nullptr),
mBlobManager(nullptr), mOwnsBlob(true), mBlobIsFile(aBlobIsFile)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!mBlob);
MOZ_ASSERT(!mRemoteMultipartBlob);
MOZ_ASSERT(!mOwnsBlob);
MOZ_ASSERT(aBlob);
if (NS_FAILED(aBlob->SetMutable(false))) { SetRemoteBlob(remoteBlob);
MOZ_NOT_REACHED("Failed to make remote blob immutable!");
}
aBlob->SetPBlob(this);
aBlob.forget(&mRemoteMultipartBlob);
mBlob = mRemoteMultipartBlob;
} }
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
@@ -1140,117 +1004,21 @@ Blob<ActorFlavor>::Create(const BlobConstructorParams& aParams)
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
switch (aParams.type()) { switch (aParams.type()) {
case BlobConstructorParams::TBlobConstructorNoMultipartParams: { case BlobConstructorParams::TNormalBlobConstructorParams:
const BlobConstructorNoMultipartParams& params = case BlobConstructorParams::TFileBlobConstructorParams:
aParams.get_BlobConstructorNoMultipartParams(); case BlobConstructorParams::TMysteryBlobConstructorParams:
return new Blob<ActorFlavor>(aParams);
switch (params.type()) { case BlobConstructorParams::TSlicedBlobConstructorParams: {
case BlobConstructorNoMultipartParams::TBlobOrFileConstructorParams: { const SlicedBlobConstructorParams& params =
const BlobOrFileConstructorParams& fileParams = aParams.get_SlicedBlobConstructorParams();
params.get_BlobOrFileConstructorParams();
nsRefPtr<RemoteBlobType> remoteBlob;
bool isFile = false;
switch (fileParams.type()) { nsCOMPtr<nsIDOMBlob> source = GetBlobFromParams<ActorFlavor>(params);
case BlobOrFileConstructorParams::TNormalBlobConstructorParams: {
const NormalBlobConstructorParams& normalParams =
fileParams.get_NormalBlobConstructorParams();
remoteBlob = new RemoteBlobType(normalParams.contentType(),
normalParams.length());
break;
}
case BlobOrFileConstructorParams::TFileBlobConstructorParams: {
const FileBlobConstructorParams& fbParams =
fileParams.get_FileBlobConstructorParams();
remoteBlob =
new RemoteBlobType(fbParams.name(), fbParams.contentType(),
fbParams.length(), fbParams.modDate());
isFile = true;
break;
}
default:
MOZ_NOT_REACHED("Unknown params!");
}
return new Blob<ActorFlavor>(remoteBlob, isFile);
}
case BlobConstructorNoMultipartParams::TMemoryBlobOrFileConstructorParams: {
const MemoryBlobOrFileConstructorParams& memoryParams =
params.get_MemoryBlobOrFileConstructorParams();
const BlobOrFileConstructorParams& internalParams =
memoryParams.constructorParams();
nsRefPtr<RemoteMemoryBlobType> remoteMemoryBlob;
bool isFile = false;
switch (internalParams.type()) {
case BlobOrFileConstructorParams::TNormalBlobConstructorParams: {
const NormalBlobConstructorParams& normalParams =
internalParams.get_NormalBlobConstructorParams();
MOZ_ASSERT(normalParams.length() == memoryParams.data().Length());
void* data =
BlobTraits<ActorFlavor>::Allocate(memoryParams.data().Length());
if (!data) {
return nullptr;
}
memcpy(data,
memoryParams.data().Elements(),
memoryParams.data().Length());
remoteMemoryBlob =
new RemoteMemoryBlobType(data,
memoryParams.data().Length(),
normalParams.contentType());
break;
}
case BlobOrFileConstructorParams::TFileBlobConstructorParams: {
const FileBlobConstructorParams& fbParams =
internalParams.get_FileBlobConstructorParams();
MOZ_ASSERT(fbParams.length() == memoryParams.data().Length());
void* data =
BlobTraits<ActorFlavor>::Allocate(memoryParams.data().Length());
if (!data) {
return nullptr;
}
memcpy(data,
memoryParams.data().Elements(),
memoryParams.data().Length());
remoteMemoryBlob =
new RemoteMemoryBlobType(data,
memoryParams.data().Length(),
fbParams.name(),
fbParams.contentType(),
fbParams.modDate());
isFile = true;
break;
}
default:
MOZ_NOT_REACHED("Unknown params!");
}
return new Blob<ActorFlavor>(remoteMemoryBlob, isFile);
}
case BlobConstructorNoMultipartParams::TMysteryBlobConstructorParams: {
nsRefPtr<RemoteBlobType> remoteBlob = new RemoteBlobType();
return new Blob<ActorFlavor>(remoteBlob, true);
}
case BlobConstructorNoMultipartParams::TSlicedBlobConstructorParams: {
const SlicedBlobConstructorParams& slicedParams =
params.get_SlicedBlobConstructorParams();
nsCOMPtr<nsIDOMBlob> source =
GetBlobFromParams<ActorFlavor>(slicedParams);
MOZ_ASSERT(source); MOZ_ASSERT(source);
nsCOMPtr<nsIDOMBlob> slice; nsCOMPtr<nsIDOMBlob> slice;
nsresult rv = nsresult rv =
source->Slice(slicedParams.begin(), slicedParams.end(), source->Slice(params.begin(), params.end(), params.contentType(), 3,
slicedParams.contentType(), 3,
getter_AddRefs(slice)); getter_AddRefs(slice));
NS_ENSURE_SUCCESS(rv, nullptr); NS_ENSURE_SUCCESS(rv, nullptr);
@@ -1260,41 +1028,6 @@ Blob<ActorFlavor>::Create(const BlobConstructorParams& aParams)
default: default:
MOZ_NOT_REACHED("Unknown params!"); MOZ_NOT_REACHED("Unknown params!");
} }
}
case BlobConstructorParams::TMultipartBlobOrFileConstructorParams: {
const MultipartBlobOrFileConstructorParams& params =
aParams.get_MultipartBlobOrFileConstructorParams();
nsRefPtr<RemoteMultipartBlobType> file;
const BlobOrFileConstructorParams& internalParams =
params.constructorParams();
switch (internalParams.type()) {
case BlobOrFileConstructorParams::TNormalBlobConstructorParams: {
const NormalBlobConstructorParams& normalParams =
internalParams.get_NormalBlobConstructorParams();
file = new RemoteMultipartBlobType(normalParams.contentType());
break;
}
case BlobOrFileConstructorParams::TFileBlobConstructorParams: {
const FileBlobConstructorParams& fbParams =
internalParams.get_FileBlobConstructorParams();
file = new RemoteMultipartBlobType(fbParams.name(),
fbParams.contentType());
break;
}
default:
MOZ_NOT_REACHED("Unknown params!");
}
return new Blob<ActorFlavor>(file);
}
default:
MOZ_NOT_REACHED("Unknown params!");
}
return nullptr; return nullptr;
} }
@@ -1311,8 +1044,7 @@ Blob<ActorFlavor>::GetBlob()
// Remote blobs are held alive until the first call to GetBlob. Thereafter we // Remote blobs are held alive until the first call to GetBlob. Thereafter we
// only hold a weak reference. Normal blobs are held alive until the actor is // only hold a weak reference. Normal blobs are held alive until the actor is
// destroyed. // destroyed.
if (mOwnsBlob && if (mRemoteBlob && mOwnsBlob) {
(mRemoteBlob || mRemoteMemoryBlob || mRemoteMultipartBlob)) {
blob = dont_AddRef(mBlob); blob = dont_AddRef(mBlob);
mOwnsBlob = false; mOwnsBlob = false;
} }
@@ -1367,53 +1099,24 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aContentType,
} }
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
typename Blob<ActorFlavor>::ProtocolType* void
Blob<ActorFlavor>::ConstructPBlobOnManager(ProtocolType* aActor, Blob<ActorFlavor>::SetRemoteBlob(nsRefPtr<RemoteBlobType>& aRemoteBlob)
const BlobConstructorParams& aParams)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(HasManager()); MOZ_ASSERT(!mBlob);
MOZ_ASSERT(!mRemoteBlob);
MOZ_ASSERT(!mOwnsBlob);
MOZ_ASSERT(aRemoteBlob);
if (mContentManager) { if (NS_FAILED(aRemoteBlob->SetMutable(false))) {
return mContentManager->SendPBlobConstructor(aActor, aParams); MOZ_NOT_REACHED("Failed to make remote blob immutable!");
} }
if (mBlobManager) { aRemoteBlob->SetActor(this);
return mBlobManager->SendPBlobConstructor(aActor, aParams); aRemoteBlob.forget(&mRemoteBlob);
}
MOZ_NOT_REACHED("Why don't I have a manager?!"); mBlob = mRemoteBlob;
return nullptr; mOwnsBlob = true;
}
template <ActorFlavorEnum ActorFlavor>
void
Blob<ActorFlavor>::SetManager(ContentManagerType* aManager)
{
MOZ_ASSERT(!mContentManager && !mBlobManager);
MOZ_ASSERT(aManager);
mContentManager = aManager;
}
template <ActorFlavorEnum ActorFlavor>
void
Blob<ActorFlavor>::SetManager(BlobManagerType* aManager)
{
MOZ_ASSERT(!mContentManager && !mBlobManager);
MOZ_ASSERT(aManager);
mBlobManager = aManager;
}
template <ActorFlavorEnum ActorFlavor>
void
Blob<ActorFlavor>::PropagateManager(Blob<ActorFlavor>* aActor) const
{
MOZ_ASSERT(HasManager());
aActor->mContentManager = mContentManager;
aActor->mBlobManager = mBlobManager;
} }
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
@@ -1421,7 +1124,7 @@ void
Blob<ActorFlavor>::NoteDyingRemoteBlob() Blob<ActorFlavor>::NoteDyingRemoteBlob()
{ {
MOZ_ASSERT(mBlob); MOZ_ASSERT(mBlob);
MOZ_ASSERT(mRemoteBlob || mRemoteMemoryBlob || mRemoteMultipartBlob); MOZ_ASSERT(mRemoteBlob);
MOZ_ASSERT(!mOwnsBlob); MOZ_ASSERT(!mOwnsBlob);
// This may be called on any thread due to the fact that RemoteBlob is // This may be called on any thread due to the fact that RemoteBlob is
@@ -1441,8 +1144,6 @@ Blob<ActorFlavor>::NoteDyingRemoteBlob()
// Must do this before calling Send__delete__ or we'll crash there trying to // Must do this before calling Send__delete__ or we'll crash there trying to
// access a dangling pointer. // access a dangling pointer.
mRemoteBlob = nullptr; mRemoteBlob = nullptr;
mRemoteMemoryBlob = nullptr;
mRemoteMultipartBlob = nullptr;
mozilla::unused << ProtocolType::Send__delete__(this); mozilla::unused << ProtocolType::Send__delete__(this);
} }
@@ -1455,15 +1156,7 @@ Blob<ActorFlavor>::ActorDestroy(ActorDestroyReason aWhy)
MOZ_ASSERT(mBlob); MOZ_ASSERT(mBlob);
if (mRemoteBlob) { if (mRemoteBlob) {
mRemoteBlob->SetPBlob(nullptr); mRemoteBlob->SetActor(nullptr);
}
if (mRemoteMemoryBlob) {
mRemoteMemoryBlob->SetPBlob(nullptr);
}
if (mRemoteMultipartBlob) {
mRemoteMultipartBlob->SetPBlob(nullptr);
} }
if (mOwnsBlob) { if (mOwnsBlob) {
@@ -1478,8 +1171,6 @@ Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob); MOZ_ASSERT(mBlob);
MOZ_ASSERT(!mRemoteBlob); MOZ_ASSERT(!mRemoteBlob);
MOZ_ASSERT(!mRemoteMemoryBlob);
MOZ_ASSERT(!mRemoteMultipartBlob);
MOZ_ASSERT(mOwnsBlob); MOZ_ASSERT(mOwnsBlob);
if (!mBlobIsFile) { if (!mBlobIsFile) {
@@ -1522,8 +1213,6 @@ Blob<Parent>::RecvPBlobStreamConstructor(StreamType* aActor)
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob); MOZ_ASSERT(mBlob);
MOZ_ASSERT(!mRemoteBlob); MOZ_ASSERT(!mRemoteBlob);
MOZ_ASSERT(!mRemoteMemoryBlob);
MOZ_ASSERT(!mRemoteMultipartBlob);
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream)); nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream));
@@ -1579,8 +1268,6 @@ Blob<Child>::RecvPBlobStreamConstructor(StreamType* aActor)
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob); MOZ_ASSERT(mBlob);
MOZ_ASSERT(!mRemoteBlob); MOZ_ASSERT(!mRemoteBlob);
MOZ_ASSERT(!mRemoteMemoryBlob);
MOZ_ASSERT(!mRemoteMultipartBlob);
nsCOMPtr<nsIInputStream> stream; nsCOMPtr<nsIInputStream> stream;
nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream)); nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream));
@@ -1601,25 +1288,6 @@ Blob<Child>::RecvPBlobStreamConstructor(StreamType* aActor)
return aActor->Send__delete__(aActor, params); return aActor->Send__delete__(aActor, params);
} }
template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::RecvPBlobConstructor(ProtocolType* aActor,
const BlobConstructorParams& aParams)
{
MOZ_ASSERT(NS_IsMainThread());
Blob<ActorFlavor>* subBlobActor = static_cast<Blob<ActorFlavor>*>(aActor);
if (!subBlobActor->ManagerIs(this)) {
// Somebody screwed up!
return false;
}
nsCOMPtr<nsIDOMBlob> blob = subBlobActor->GetBlob();
static_cast<nsDOMMultipartFile*>(mBlob)->AddBlob(blob);
return true;
}
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
typename Blob<ActorFlavor>::StreamType* typename Blob<ActorFlavor>::StreamType*
Blob<ActorFlavor>::AllocPBlobStream() Blob<ActorFlavor>::AllocPBlobStream()
@@ -1637,23 +1305,6 @@ Blob<ActorFlavor>::DeallocPBlobStream(StreamType* aActor)
return true; return true;
} }
template <ActorFlavorEnum ActorFlavor>
typename Blob<ActorFlavor>::ProtocolType*
Blob<ActorFlavor>::AllocPBlob(const BlobConstructorParams& aParams)
{
Blob<ActorFlavor>* actor = Blob<ActorFlavor>::Create(aParams);
actor->SetManager(this);
return actor;
}
template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::DeallocPBlob(ProtocolType* aActor)
{
delete aActor;
return true;
}
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
NS_IMPL_ADDREF_INHERITED(RemoteBlob<ActorFlavor>, nsDOMFile) NS_IMPL_ADDREF_INHERITED(RemoteBlob<ActorFlavor>, nsDOMFile)
@@ -1664,26 +1315,6 @@ template <ActorFlavorEnum ActorFlavor>
NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteBlob<ActorFlavor>, nsDOMFile, NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteBlob<ActorFlavor>, nsDOMFile,
nsIRemoteBlob) nsIRemoteBlob)
template <ActorFlavorEnum ActorFlavor>
NS_IMPL_ADDREF_INHERITED(RemoteMemoryBlob<ActorFlavor>, nsDOMMemoryFile)
template <ActorFlavorEnum ActorFlavor>
NS_IMPL_RELEASE_INHERITED(RemoteMemoryBlob<ActorFlavor>, nsDOMMemoryFile)
template <ActorFlavorEnum ActorFlavor>
NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteMemoryBlob<ActorFlavor>, nsDOMMemoryFile,
nsIRemoteBlob)
template <ActorFlavorEnum ActorFlavor>
NS_IMPL_ADDREF_INHERITED(RemoteMultipartBlob<ActorFlavor>, nsDOMMultipartFile)
template <ActorFlavorEnum ActorFlavor>
NS_IMPL_RELEASE_INHERITED(RemoteMultipartBlob<ActorFlavor>, nsDOMMultipartFile)
template <ActorFlavorEnum ActorFlavor>
NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteMultipartBlob<ActorFlavor>, nsDOMMultipartFile,
nsIRemoteBlob)
// Explicit instantiation of both classes. // Explicit instantiation of both classes.
template class Blob<Parent>; template class Blob<Parent>;
template class Blob<Child>; template class Blob<Child>;

View File

@@ -42,8 +42,6 @@ struct BlobTraits<Parent>
{ {
typedef mozilla::dom::PBlobParent ProtocolType; typedef mozilla::dom::PBlobParent ProtocolType;
typedef mozilla::dom::PBlobStreamParent StreamType; typedef mozilla::dom::PBlobStreamParent StreamType;
typedef mozilla::dom::PContentParent ContentManagerType;
typedef ProtocolType BlobManagerType;
// BaseType on the parent side is a bit more complicated than for the child // BaseType on the parent side is a bit more complicated than for the child
// side. In the case of nsIInputStreams backed by files we need to ensure that // side. In the case of nsIInputStreams backed by files we need to ensure that
@@ -68,13 +66,6 @@ struct BlobTraits<Parent>
nsTArray<nsRevocableEventPtr<OpenStreamRunnable> > mOpenStreamRunnables; nsTArray<nsRevocableEventPtr<OpenStreamRunnable> > mOpenStreamRunnables;
}; };
static void*
Allocate(size_t aSize)
{
// We want fallible allocation in the parent.
return moz_malloc(aSize);
}
}; };
template <> template <>
@@ -82,8 +73,6 @@ struct BlobTraits<Child>
{ {
typedef mozilla::dom::PBlobChild ProtocolType; typedef mozilla::dom::PBlobChild ProtocolType;
typedef mozilla::dom::PBlobStreamChild StreamType; typedef mozilla::dom::PBlobStreamChild StreamType;
typedef mozilla::dom::PContentChild ContentManagerType;
typedef ProtocolType BlobManagerType;
class BaseType : public ProtocolType class BaseType : public ProtocolType
{ {
@@ -94,38 +83,21 @@ struct BlobTraits<Child>
virtual ~BaseType() virtual ~BaseType()
{ } { }
}; };
static void*
Allocate(size_t aSize)
{
// We want infallible allocation in the child.
return moz_xmalloc(aSize);
}
}; };
template <ActorFlavorEnum>
class RemoteBlobBase;
template <ActorFlavorEnum> template <ActorFlavorEnum>
class RemoteBlob; class RemoteBlob;
template <ActorFlavorEnum>
class RemoteMemoryBlob;
template <ActorFlavorEnum>
class RemoteMultipartBlob;
template <ActorFlavorEnum ActorFlavor> template <ActorFlavorEnum ActorFlavor>
class Blob : public BlobTraits<ActorFlavor>::BaseType class Blob : public BlobTraits<ActorFlavor>::BaseType
{ {
friend class RemoteBlobBase<ActorFlavor>; friend class RemoteBlob<ActorFlavor>;
public: public:
typedef typename BlobTraits<ActorFlavor>::ProtocolType ProtocolType; typedef typename BlobTraits<ActorFlavor>::ProtocolType ProtocolType;
typedef typename BlobTraits<ActorFlavor>::StreamType StreamType; typedef typename BlobTraits<ActorFlavor>::StreamType StreamType;
typedef typename BlobTraits<ActorFlavor>::BaseType BaseType; typedef typename BlobTraits<ActorFlavor>::BaseType BaseType;
typedef typename BlobTraits<ActorFlavor>::ContentManagerType ContentManagerType;
typedef typename BlobTraits<ActorFlavor>::BlobManagerType BlobManagerType;
typedef RemoteBlob<ActorFlavor> RemoteBlobType; typedef RemoteBlob<ActorFlavor> RemoteBlobType;
typedef RemoteMemoryBlob<ActorFlavor> RemoteMemoryBlobType;
typedef RemoteMultipartBlob<ActorFlavor> RemoteMultipartBlobType;
typedef mozilla::ipc::IProtocolManager< typedef mozilla::ipc::IProtocolManager<
mozilla::ipc::RPCChannel::RPCListener>::ActorDestroyReason mozilla::ipc::RPCChannel::RPCListener>::ActorDestroyReason
ActorDestroyReason; ActorDestroyReason;
@@ -134,12 +106,6 @@ public:
protected: protected:
nsIDOMBlob* mBlob; nsIDOMBlob* mBlob;
RemoteBlobType* mRemoteBlob; RemoteBlobType* mRemoteBlob;
RemoteMemoryBlobType* mRemoteMemoryBlob;
RemoteMultipartBlobType* mRemoteMultipartBlob;
ContentManagerType* mContentManager;
BlobManagerType* mBlobManager;
bool mOwnsBlob; bool mOwnsBlob;
bool mBlobIsFile; bool mBlobIsFile;
@@ -170,49 +136,15 @@ public:
bool bool
SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength); SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
ProtocolType*
ConstructPBlobOnManager(ProtocolType* aActor,
const BlobConstructorParams& aParams);
bool
ManagerIs(const ContentManagerType* aManager) const
{
return aManager == mContentManager;
}
bool
ManagerIs(const BlobManagerType* aManager) const
{
return aManager == mBlobManager;
}
#ifdef DEBUG
bool
HasManager() const
{
return !!mContentManager || !!mBlobManager;
}
#endif
void
SetManager(ContentManagerType* aManager);
void
SetManager(BlobManagerType* aManager);
void
PropagateManager(Blob<ActorFlavor>* aActor) const;
private: private:
// This constructor is called on the sending side. // This constructor is called on the sending side.
Blob(nsIDOMBlob* aBlob); Blob(nsIDOMBlob* aBlob);
// These constructors are called on the receiving side. // This constructor is called on the receiving side.
Blob(nsRefPtr<RemoteBlobType>& aBlob, Blob(const BlobConstructorParams& aParams);
bool aIsFile);
Blob(nsRefPtr<RemoteMemoryBlobType>& aBlob, void
bool aIsFile); SetRemoteBlob(nsRefPtr<RemoteBlobType>& aRemoteBlob);
Blob(nsRefPtr<RemoteMultipartBlobType>& aBlob,
bool aIsFile);
void void
NoteDyingRemoteBlob(); NoteDyingRemoteBlob();
@@ -227,21 +159,11 @@ private:
virtual bool virtual bool
RecvPBlobStreamConstructor(StreamType* aActor) MOZ_OVERRIDE; RecvPBlobStreamConstructor(StreamType* aActor) MOZ_OVERRIDE;
virtual bool
RecvPBlobConstructor(ProtocolType* aActor,
const BlobConstructorParams& aParams) MOZ_OVERRIDE;
virtual StreamType* virtual StreamType*
AllocPBlobStream() MOZ_OVERRIDE; AllocPBlobStream() MOZ_OVERRIDE;
virtual bool virtual bool
DeallocPBlobStream(StreamType* aActor) MOZ_OVERRIDE; DeallocPBlobStream(StreamType* aActor) MOZ_OVERRIDE;
virtual ProtocolType*
AllocPBlob(const BlobConstructorParams& params) MOZ_OVERRIDE;
virtual bool
DeallocPBlob(ProtocolType* actor) MOZ_OVERRIDE;
}; };
} // namespace ipc } // namespace ipc

View File

@@ -546,9 +546,7 @@ ContentChild::DeallocPBrowser(PBrowserChild* iframe)
PBlobChild* PBlobChild*
ContentChild::AllocPBlob(const BlobConstructorParams& aParams) ContentChild::AllocPBlob(const BlobConstructorParams& aParams)
{ {
BlobChild* actor = BlobChild::Create(aParams); return BlobChild::Create(aParams);
actor->SetManager(this);
return actor;
} }
bool bool
@@ -558,42 +556,53 @@ ContentChild::DeallocPBlob(PBlobChild* aActor)
return true; return true;
} }
bool BlobChild*
ContentChild::GetParamsForBlob(nsDOMFileBase* aBlob, ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
BlobConstructorParams* aOutParams)
{ {
BlobConstructorParams resultParams; NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aBlob, "Null pointer!");
if (!(aBlob->IsMemoryBacked() || aBlob->GetSubBlobs()) && nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
(aBlob->IsSizeUnknown() || aBlob->IsDateUnknown())) { if (remoteBlob) {
BlobChild* actor =
static_cast<BlobChild*>(static_cast<PBlobChild*>(remoteBlob->GetPBlob()));
NS_ASSERTION(actor, "Null actor?!");
return actor;
}
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
const nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
BlobConstructorParams params;
if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
// We don't want to call GetSize or GetLastModifiedDate // We don't want to call GetSize or GetLastModifiedDate
// yet since that may stat a file on the main thread // yet since that may stat a file on the main thread
// here. Instead we'll learn the size lazily from the // here. Instead we'll learn the size lazily from the
// other process. // other process.
resultParams = MysteryBlobConstructorParams(); params = MysteryBlobConstructorParams();
} }
else { else {
BlobOrFileConstructorParams params;
nsString contentType; nsString contentType;
nsresult rv = aBlob->GetType(contentType); nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, nullptr);
uint64_t length; uint64_t length;
rv = aBlob->GetSize(&length); rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIDOMFile> file; nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
static_cast<nsIDOMBlob*>(aBlob)->QueryInterface(NS_GET_IID(nsIDOMFile),
(void**)getter_AddRefs(file));
if (file) { if (file) {
FileBlobConstructorParams fileParams; FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name()); rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetMozLastModifiedDate(&fileParams.modDate()); rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType; fileParams.contentType() = contentType;
fileParams.length() = length; fileParams.length() = length;
@@ -605,83 +614,15 @@ ContentChild::GetParamsForBlob(nsDOMFileBase* aBlob,
blobParams.length() = length; blobParams.length() = length;
params = blobParams; params = blobParams;
} }
MOZ_ASSERT(!(aBlob->IsMemoryBacked() &&
aBlob->GetSubBlobs()), "Can't be both!");
if (aBlob->IsMemoryBacked()) {
const nsDOMMemoryFile* memoryBlob =
static_cast<const nsDOMMemoryFile*>(aBlob);
InfallibleTArray<uint8_t> data;
data.SetLength(memoryBlob->GetLength());
memcpy(data.Elements(), memoryBlob->GetData(), memoryBlob->GetLength());
MemoryBlobOrFileConstructorParams memoryParams(params, data);
resultParams = memoryParams;
}
else if (aBlob->GetSubBlobs()) {
MultipartBlobOrFileConstructorParams multipartParams(params);
resultParams = multipartParams;
}
else {
resultParams = BlobConstructorNoMultipartParams(params);
}
}
*aOutParams = resultParams;
return true;
}
BlobChild*
ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aBlob, "Null pointer!");
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
if (remoteBlob) {
BlobChild* actor =
static_cast<BlobChild*>(static_cast<PBlobChild*>(remoteBlob->GetPBlob()));
NS_ASSERTION(actor, "Null actor?!");
return actor;
}
BlobConstructorParams params;
if (!GetParamsForBlob(blob, &params)) {
return nullptr;
} }
BlobChild* actor = BlobChild::Create(aBlob); BlobChild* actor = BlobChild::Create(aBlob);
NS_ENSURE_TRUE(actor, nullptr); NS_ENSURE_TRUE(actor, nullptr);
SendPBlobConstructor(actor, params); if (!SendPBlobConstructor(actor, params)) {
actor->SetManager(this);
if (const nsTArray<nsCOMPtr<nsIDOMBlob> >* subBlobs = blob->GetSubBlobs()) {
for (uint32_t i = 0; i < subBlobs->Length(); ++i) {
BlobConstructorParams subParams;
nsDOMFileBase* subBlob =
static_cast<nsDOMFileBase*>(subBlobs->ElementAt(i).get());
if (!GetParamsForBlob(subBlob, &subParams)) {
return nullptr; return nullptr;
} }
BlobChild* subActor = BlobChild::Create(aBlob);
actor->SendPBlobConstructor(subActor, subParams);
subActor->SetManager(actor);
}
}
return actor; return actor;
} }

View File

@@ -17,7 +17,6 @@
struct ChromePackage; struct ChromePackage;
class nsIDOMBlob; class nsIDOMBlob;
class nsDOMFileBase;
class nsIObserver; class nsIObserver;
struct ResourceMapping; struct ResourceMapping;
struct OverrideMapping; struct OverrideMapping;
@@ -199,8 +198,6 @@ public:
uint64_t GetID() { return mID; } uint64_t GetID() { return mID; }
bool GetParamsForBlob(nsDOMFileBase* aBlob,
BlobConstructorParams* aOutParams);
BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob); BlobChild* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
private: private:

View File

@@ -1418,9 +1418,7 @@ ContentParent::DeallocPDeviceStorageRequest(PDeviceStorageRequestParent* doomed)
PBlobParent* PBlobParent*
ContentParent::AllocPBlob(const BlobConstructorParams& aParams) ContentParent::AllocPBlob(const BlobConstructorParams& aParams)
{ {
BlobParent* actor = BlobParent::Create(aParams); return BlobParent::Create(aParams);
actor->SetManager(this);
return actor;
} }
bool bool
@@ -1430,42 +1428,56 @@ ContentParent::DeallocPBlob(PBlobParent* aActor)
return true; return true;
} }
bool BlobParent*
ContentParent::GetParamsForBlob(nsDOMFileBase* aBlob, ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
BlobConstructorParams* aOutParams)
{ {
BlobConstructorParams resultParams; NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aBlob, "Null pointer!");
if (!(aBlob->IsMemoryBacked() || aBlob->GetSubBlobs()) && nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
(aBlob->IsSizeUnknown() || aBlob->IsDateUnknown())) { if (remoteBlob) {
BlobParent* actor =
static_cast<BlobParent*>(
static_cast<PBlobParent*>(remoteBlob->GetPBlob()));
NS_ASSERTION(actor, "Null actor?!");
if (static_cast<ContentParent*>(actor->Manager()) == this) {
return actor;
}
}
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
const nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
BlobConstructorParams params;
if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
// We don't want to call GetSize or GetLastModifiedDate // We don't want to call GetSize or GetLastModifiedDate
// yet since that may stat a file on the main thread // yet since that may stat a file on the main thread
// here. Instead we'll learn the size lazily from the // here. Instead we'll learn the size lazily from the
// other process. // other process.
resultParams = MysteryBlobConstructorParams(); params = MysteryBlobConstructorParams();
} }
else { else {
BlobOrFileConstructorParams params;
nsString contentType; nsString contentType;
nsresult rv = aBlob->GetType(contentType); nsresult rv = aBlob->GetType(contentType);
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, nullptr);
uint64_t length; uint64_t length;
rv = aBlob->GetSize(&length); rv = aBlob->GetSize(&length);
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIDOMFile> file; nsCOMPtr<nsIDOMFile> file = do_QueryInterface(aBlob);
static_cast<nsIDOMBlob*>(aBlob)->QueryInterface(NS_GET_IID(nsIDOMFile),
(void**)getter_AddRefs(file));
if (file) { if (file) {
FileBlobConstructorParams fileParams; FileBlobConstructorParams fileParams;
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, false);
rv = file->GetMozLastModifiedDate(&fileParams.modDate()); rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, false); NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType; fileParams.contentType() = contentType;
fileParams.length() = length; fileParams.length() = length;
@@ -1477,63 +1489,6 @@ ContentParent::GetParamsForBlob(nsDOMFileBase* aBlob,
blobParams.length() = length; blobParams.length() = length;
params = blobParams; params = blobParams;
} }
MOZ_ASSERT(!(aBlob->IsMemoryBacked() &&
aBlob->GetSubBlobs()), "Can't be both!");
if (aBlob->IsMemoryBacked()) {
const nsDOMMemoryFile* memoryBlob =
static_cast<const nsDOMMemoryFile*>(aBlob);
FallibleTArray<uint8_t> data;
if (!data.SetLength(memoryBlob->GetLength())) {
return false;
}
memcpy(data.Elements(), memoryBlob->GetData(), memoryBlob->GetLength());
MemoryBlobOrFileConstructorParams memoryParams(params, data);
resultParams = memoryParams;
}
else if (aBlob->GetSubBlobs()) {
MultipartBlobOrFileConstructorParams multipartParams(params);
resultParams = multipartParams;
}
else {
resultParams = BlobConstructorNoMultipartParams(params);
}
}
*aOutParams = resultParams;
return true;
}
BlobParent*
ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(aBlob, "Null pointer!");
// XXX This is only safe so long as all blob implementations in our tree
// inherit nsDOMFileBase. If that ever changes then this will need to grow
// a real interface or something.
nsDOMFileBase* blob = static_cast<nsDOMFileBase*>(aBlob);
nsCOMPtr<nsIRemoteBlob> remoteBlob = do_QueryInterface(aBlob);
if (remoteBlob) {
BlobParent* actor =
static_cast<BlobParent*>(
static_cast<PBlobParent*>(remoteBlob->GetPBlob()));
NS_ASSERTION(actor, "Null actor?!");
if (actor->ManagerIs(this)) {
return actor;
}
}
BlobConstructorParams params;
if (!GetParamsForBlob(blob, &params)) {
return nullptr;
} }
BlobParent* actor = BlobParent::Create(aBlob); BlobParent* actor = BlobParent::Create(aBlob);
@@ -1543,26 +1498,6 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
return nullptr; return nullptr;
} }
actor->SetManager(this);
if (const nsTArray<nsCOMPtr<nsIDOMBlob> >* subBlobs = blob->GetSubBlobs()) {
for (uint32_t i = 0; i < subBlobs->Length(); ++i) {
BlobConstructorParams subParams;
nsDOMFileBase* subBlob =
static_cast<nsDOMFileBase*>(subBlobs->ElementAt(i).get());
if (!GetParamsForBlob(subBlob, &subParams)) {
return nullptr;
}
BlobParent* subActor = BlobParent::Create(aBlob);
if (!actor->SendPBlobConstructor(subActor, subParams)) {
return nullptr;
}
subActor->SetManager(actor);
}
}
return actor; return actor;
} }

View File

@@ -35,7 +35,6 @@
class mozIApplication; class mozIApplication;
class nsConsoleService; class nsConsoleService;
class nsIDOMBlob; class nsIDOMBlob;
class nsDOMFileBase;
namespace mozilla { namespace mozilla {
@@ -131,9 +130,8 @@ public:
return mSendPermissionUpdates; return mSendPermissionUpdates;
} }
bool GetParamsForBlob(nsDOMFileBase* aBlob,
BlobConstructorParams* aOutParams);
BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob); BlobParent* GetOrCreateActorForBlob(nsIDOMBlob* aBlob);
/** /**
* Kill our subprocess and make sure it dies. Should only be used * Kill our subprocess and make sure it dies. Should only be used
* in emergency situations since it bypasses the normal shutdown * in emergency situations since it bypasses the normal shutdown

View File

@@ -31,49 +31,5 @@ struct FileBlobConstructorParams
uint64_t modDate; uint64_t modDate;
}; };
union BlobOrFileConstructorParams
{
NormalBlobConstructorParams;
FileBlobConstructorParams;
};
struct MemoryBlobOrFileConstructorParams
{
BlobOrFileConstructorParams constructorParams;
uint8_t[] data;
};
struct SlicedBlobConstructorParams
{
PBlob source;
uint64_t begin;
uint64_t end;
nsString contentType;
};
struct MysteryBlobConstructorParams
{
// Nothing is known about this type of blob.
};
union BlobConstructorNoMultipartParams
{
BlobOrFileConstructorParams;
MemoryBlobOrFileConstructorParams;
SlicedBlobConstructorParams;
MysteryBlobConstructorParams;
};
struct MultipartBlobOrFileConstructorParams
{
BlobOrFileConstructorParams constructorParams;
};
union BlobConstructorParams
{
BlobConstructorNoMultipartParams;
MultipartBlobOrFileConstructorParams;
};
} // namespace dom } // namespace dom
} // namespace mozilla } // namespace mozilla

View File

@@ -18,14 +18,12 @@ union ResolveMysteryParams
protocol PBlob protocol PBlob
{ {
manager PContent or PBlob; manager PContent;
manages PBlobStream; manages PBlobStream;
manages PBlob;
both: both:
__delete__(); __delete__();
PBlob(BlobConstructorParams params);
PBlobStream(); PBlobStream();
ResolveMystery(ResolveMysteryParams params); ResolveMystery(ResolveMysteryParams params);

View File

@@ -117,6 +117,27 @@ union DeviceStorageParams
DeviceStorageStatParams; DeviceStorageStatParams;
}; };
struct SlicedBlobConstructorParams
{
PBlob source;
uint64_t begin;
uint64_t end;
nsString contentType;
};
struct MysteryBlobConstructorParams
{
// Nothing is known about this type of blob.
};
union BlobConstructorParams
{
NormalBlobConstructorParams;
FileBlobConstructorParams;
SlicedBlobConstructorParams;
MysteryBlobConstructorParams;
};
// An IPCTabContext which corresponds to a PBrowser opened by a child when it // An IPCTabContext which corresponds to a PBrowser opened by a child when it
// receives window.open(). // receives window.open().
// //

View File

@@ -12,7 +12,7 @@
#endif #endif
#define NS_IREMOTEBLOB_IID \ #define NS_IREMOTEBLOB_IID \
{0x1f569fbc, 0xf588, 0x41c5, {0xa0, 0x73, 0x92, 0x0d, 0xf5, 0x9f, 0x1b, 0xdb}} {0x74ce3cdd, 0xbfc9, 0x4edb, {0x98, 0x26, 0x50, 0xcf, 0x00, 0x26, 0x58, 0x70}}
class NS_NO_VTABLE nsIRemoteBlob : public nsISupports class NS_NO_VTABLE nsIRemoteBlob : public nsISupports
{ {
@@ -21,8 +21,6 @@ public:
// This will either return a PBlobChild or PBlobParent. // This will either return a PBlobChild or PBlobParent.
virtual void* GetPBlob() = 0; virtual void* GetPBlob() = 0;
virtual void SetPBlob(void* aActor) = 0;
}; };
NS_DEFINE_STATIC_IID_ACCESSOR(nsIRemoteBlob, NS_IREMOTEBLOB_IID) NS_DEFINE_STATIC_IID_ACCESSOR(nsIRemoteBlob, NS_IREMOTEBLOB_IID)

View File

@@ -87,7 +87,7 @@ private:
static JSBool static JSBool
Construct(JSContext* aCx, unsigned aArgc, jsval* aVp) Construct(JSContext* aCx, unsigned aArgc, jsval* aVp)
{ {
nsRefPtr<nsDOMMultipartFile> file = new nsDOMMultipartFile(EmptyString()); nsRefPtr<nsDOMMultipartFile> file = new nsDOMMultipartFile();
nsresult rv = file->InitBlob(aCx, aArgc, JS_ARGV(aCx, aVp), Unwrap); nsresult rv = file->InitBlob(aCx, aArgc, JS_ARGV(aCx, aVp), Unwrap);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
ThrowDOMExceptionForNSResult(aCx, rv); ThrowDOMExceptionForNSResult(aCx, rv);