Bug 966439 - BroadcastChannel API - patch 9 - Fix a memory leak of Files, r=bent

This commit is contained in:
Andrea Marchesini 2015-01-14 11:52:21 +00:00
parent 9fc9d93914
commit 81a3ef4473
5 changed files with 45 additions and 16 deletions

View File

@ -21,6 +21,10 @@
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsISupportsPrimitives.h" #include "nsISupportsPrimitives.h"
#ifdef XP_WIN
#undef PostMessage
#endif
namespace mozilla { namespace mozilla {
using namespace ipc; using namespace ipc;
@ -416,7 +420,7 @@ BroadcastChannel::BroadcastChannel(nsPIDOMWindow* aWindow,
const nsAString& aChannel) const nsAString& aChannel)
: DOMEventTargetHelper(aWindow) : DOMEventTargetHelper(aWindow)
, mWorkerFeature(nullptr) , mWorkerFeature(nullptr)
, mPrincipalInfo(aPrincipalInfo) , mPrincipalInfo(new PrincipalInfo(aPrincipalInfo))
, mOrigin(aOrigin) , mOrigin(aOrigin)
, mChannel(aChannel) , mChannel(aChannel)
, mIsKeptAlive(false) , mIsKeptAlive(false)
@ -558,6 +562,14 @@ BroadcastChannel::PostMessageInternal(JSContext* aCx,
return; return;
} }
const nsTArray<nsRefPtr<File>>& blobs = data->mClosure.mBlobs;
for (uint32_t i = 0, len = blobs.Length(); i < len; ++i) {
if (!blobs[i]->Impl()->MayBeClonedToOtherThreads()) {
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
return;
}
}
PostMessageData(data); PostMessageData(data);
} }
@ -618,7 +630,7 @@ BroadcastChannel::ActorCreated(PBackgroundChild* aActor)
} }
PBroadcastChannelChild* actor = PBroadcastChannelChild* actor =
aActor->SendPBroadcastChannelConstructor(mPrincipalInfo, mOrigin, mChannel); aActor->SendPBroadcastChannelConstructor(*mPrincipalInfo, mOrigin, mChannel);
mActor = static_cast<BroadcastChannelChild*>(actor); mActor = static_cast<BroadcastChannelChild*>(actor);
MOZ_ASSERT(mActor); MOZ_ASSERT(mActor);

View File

@ -8,7 +8,6 @@
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "mozilla/DOMEventTargetHelper.h" #include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/ipc/PBackgroundSharedTypes.h"
#include "nsIIPCBackgroundChildCreateCallback.h" #include "nsIIPCBackgroundChildCreateCallback.h"
#include "nsIObserver.h" #include "nsIObserver.h"
#include "nsTArray.h" #include "nsTArray.h"
@ -17,6 +16,11 @@
class nsPIDOMWindow; class nsPIDOMWindow;
namespace mozilla { namespace mozilla {
namespace ipc {
class PrincipalInfo;
}
namespace dom { namespace dom {
namespace workers { namespace workers {
@ -104,7 +108,8 @@ private:
workers::WorkerFeature* mWorkerFeature; workers::WorkerFeature* mWorkerFeature;
PrincipalInfo mPrincipalInfo; nsAutoPtr<PrincipalInfo> mPrincipalInfo;
nsString mOrigin; nsString mOrigin;
nsString mChannel; nsString mChannel;

View File

@ -41,6 +41,21 @@ BroadcastChannelChild::~BroadcastChannelChild()
bool bool
BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData) BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
{ {
// Make sure to retrieve all blobs from the message before returning to avoid
// leaking their actors.
nsTArray<nsRefPtr<File>> files;
if (!aData.blobsChild().IsEmpty()) {
files.SetCapacity(aData.blobsChild().Length());
for (uint32_t i = 0, len = aData.blobsChild().Length(); i < len; ++i) {
nsRefPtr<FileImpl> impl =
static_cast<BlobChild*>(aData.blobsChild()[i])->GetBlobImpl();
nsRefPtr<File> file = new File(mBC ? mBC->GetOwner() : nullptr, impl);
files.AppendElement(file);
}
}
nsCOMPtr<DOMEventTargetHelper> helper = mBC; nsCOMPtr<DOMEventTargetHelper> helper = mBC;
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(helper); nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(helper);
@ -78,18 +93,7 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
StructuredCloneData cloneData; StructuredCloneData cloneData;
cloneData.mData = buffer.data; cloneData.mData = buffer.data;
cloneData.mDataLength = buffer.dataLength; cloneData.mDataLength = buffer.dataLength;
cloneData.mClosure.mBlobs.SwapElements(files);
if (!aData.blobsChild().IsEmpty()) {
cloneData.mClosure.mBlobs.SetCapacity(aData.blobsChild().Length());
for (uint32_t i = 0, len = aData.blobsChild().Length(); i < len; ++i) {
nsRefPtr<FileImpl> impl =
static_cast<BlobChild*>(aData.blobsChild()[i])->GetBlobImpl();
nsRefPtr<File> blob = new File(mBC->GetOwner(), impl);
cloneData.mClosure.mBlobs.AppendElement(blob);
}
}
JS::Rooted<JS::Value> value(cx, JS::NullValue()); JS::Rooted<JS::Value> value(cx, JS::NullValue());
if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) { if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) {

View File

@ -7,6 +7,10 @@
#include "BroadcastChannelParent.h" #include "BroadcastChannelParent.h"
#include "mozilla/ipc/BackgroundParent.h" #include "mozilla/ipc/BackgroundParent.h"
#ifdef XP_WIN
#undef PostMessage
#endif
namespace mozilla { namespace mozilla {
using namespace ipc; using namespace ipc;

View File

@ -9,6 +9,10 @@
#include "nsHashKeys.h" #include "nsHashKeys.h"
#include "nsTHashtable.h" #include "nsTHashtable.h"
#ifdef XP_WIN
#undef PostMessage
#endif
namespace mozilla { namespace mozilla {
namespace dom { namespace dom {