mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 05:48:26 +00:00
Backed out changeset 0659c9235136 (bug 1274363) for memory leaks
--HG-- extra : rebase_source : 7fd1df522bb0cab48ca51d29140036f6a5a6a7cc
This commit is contained in:
parent
7ee9eb0799
commit
0ed94efabc
@ -18,12 +18,16 @@ using namespace ipc;
|
||||
|
||||
namespace dom {
|
||||
|
||||
BroadcastChannelParent::BroadcastChannelParent(const nsAString& aOriginChannelKey)
|
||||
BroadcastChannelParent::BroadcastChannelParent(const nsACString& aOrigin,
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
: mService(BroadcastChannelService::GetOrCreate())
|
||||
, mOriginChannelKey(aOriginChannelKey)
|
||||
, mOrigin(aOrigin)
|
||||
, mChannel(aChannel)
|
||||
, mPrivateBrowsing(aPrivateBrowsing)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
mService->RegisterActor(this, mOriginChannelKey);
|
||||
mService->RegisterActor(this);
|
||||
}
|
||||
|
||||
BroadcastChannelParent::~BroadcastChannelParent()
|
||||
@ -40,7 +44,7 @@ BroadcastChannelParent::RecvPostMessage(const ClonedMessageData& aData)
|
||||
return false;
|
||||
}
|
||||
|
||||
mService->PostMessage(this, aData, mOriginChannelKey);
|
||||
mService->PostMessage(this, aData, mOrigin, mChannel, mPrivateBrowsing);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -53,7 +57,7 @@ BroadcastChannelParent::RecvClose()
|
||||
return false;
|
||||
}
|
||||
|
||||
mService->UnregisterActor(this, mOriginChannelKey);
|
||||
mService->UnregisterActor(this);
|
||||
mService = nullptr;
|
||||
|
||||
Unused << Send__delete__(this);
|
||||
@ -69,33 +73,40 @@ BroadcastChannelParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
if (mService) {
|
||||
// This object is about to be released and with it, also mService will be
|
||||
// released too.
|
||||
mService->UnregisterActor(this, mOriginChannelKey);
|
||||
mService->UnregisterActor(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannelParent::Deliver(const ClonedMessageData& aData)
|
||||
BroadcastChannelParent::CheckAndDeliver(const ClonedMessageData& aData,
|
||||
const nsCString& aOrigin,
|
||||
const nsString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
// Duplicate the data for this parent.
|
||||
ClonedMessageData newData(aData);
|
||||
if (aOrigin == mOrigin &&
|
||||
aChannel == mChannel &&
|
||||
aPrivateBrowsing == mPrivateBrowsing) {
|
||||
// Duplicate the data for this parent.
|
||||
ClonedMessageData newData(aData);
|
||||
|
||||
// Create new BlobParent objects for this message.
|
||||
for (uint32_t i = 0, len = newData.blobsParent().Length(); i < len; ++i) {
|
||||
RefPtr<BlobImpl> impl =
|
||||
static_cast<BlobParent*>(newData.blobsParent()[i])->GetBlobImpl();
|
||||
// Ricreate the BlobParent for this new message.
|
||||
for (uint32_t i = 0, len = newData.blobsParent().Length(); i < len; ++i) {
|
||||
RefPtr<BlobImpl> impl =
|
||||
static_cast<BlobParent*>(newData.blobsParent()[i])->GetBlobImpl();
|
||||
|
||||
PBlobParent* blobParent =
|
||||
BackgroundParent::GetOrCreateActorForBlobImpl(Manager(), impl);
|
||||
if (!blobParent) {
|
||||
return;
|
||||
PBlobParent* blobParent =
|
||||
BackgroundParent::GetOrCreateActorForBlobImpl(Manager(), impl);
|
||||
if (!blobParent) {
|
||||
return;
|
||||
}
|
||||
|
||||
newData.blobsParent()[i] = blobParent;
|
||||
}
|
||||
|
||||
newData.blobsParent()[i] = blobParent;
|
||||
Unused << SendNotify(newData);
|
||||
}
|
||||
|
||||
Unused << SendNotify(newData);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
@ -27,10 +27,15 @@ class BroadcastChannelParent final : public PBroadcastChannelParent
|
||||
typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
|
||||
|
||||
public:
|
||||
void Deliver(const ClonedMessageData& aData);
|
||||
void CheckAndDeliver(const ClonedMessageData& aData,
|
||||
const nsCString& aOrigin,
|
||||
const nsString& aChannel,
|
||||
bool aPrivateBrowsing);
|
||||
|
||||
private:
|
||||
explicit BroadcastChannelParent(const nsAString& aOriginChannelKey);
|
||||
BroadcastChannelParent(const nsACString& aOrigin,
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing);
|
||||
~BroadcastChannelParent();
|
||||
|
||||
virtual bool
|
||||
@ -41,7 +46,9 @@ private:
|
||||
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
|
||||
RefPtr<BroadcastChannelService> mService;
|
||||
nsString mOriginChannelKey;
|
||||
nsCString mOrigin;
|
||||
nsString mChannel;
|
||||
bool mPrivateBrowsing;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -58,52 +58,35 @@ BroadcastChannelService::GetOrCreate()
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannelService::RegisterActor(BroadcastChannelParent* aParent,
|
||||
const nsAString& aOriginChannelKey)
|
||||
BroadcastChannelService::RegisterActor(BroadcastChannelParent* aParent)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(!mAgents.Contains(aParent));
|
||||
|
||||
nsTArray<BroadcastChannelParent*>* parents;
|
||||
if (!mAgents.Get(aOriginChannelKey, &parents)) {
|
||||
parents = new nsTArray<BroadcastChannelParent*>();
|
||||
mAgents.Put(aOriginChannelKey, parents);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!parents->Contains(aParent));
|
||||
parents->AppendElement(aParent);
|
||||
mAgents.PutEntry(aParent);
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannelService::UnregisterActor(BroadcastChannelParent* aParent,
|
||||
const nsAString& aOriginChannelKey)
|
||||
BroadcastChannelService::UnregisterActor(BroadcastChannelParent* aParent)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParent);
|
||||
MOZ_ASSERT(mAgents.Contains(aParent));
|
||||
|
||||
nsTArray<BroadcastChannelParent*>* parents;
|
||||
if (!mAgents.Get(aOriginChannelKey, &parents)) {
|
||||
MOZ_CRASH("Invalid state");
|
||||
}
|
||||
|
||||
parents->RemoveElement(aParent);
|
||||
if (parents->IsEmpty()) {
|
||||
mAgents.Remove(aOriginChannelKey);
|
||||
}
|
||||
mAgents.RemoveEntry(aParent);
|
||||
}
|
||||
|
||||
void
|
||||
BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
|
||||
const ClonedMessageData& aData,
|
||||
const nsAString& aOriginChannelKey)
|
||||
const nsACString& aOrigin,
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing)
|
||||
{
|
||||
AssertIsOnBackgroundThread();
|
||||
MOZ_ASSERT(aParent);
|
||||
|
||||
nsTArray<BroadcastChannelParent*>* parents;
|
||||
if (!mAgents.Get(aOriginChannelKey, &parents)) {
|
||||
MOZ_CRASH("Invalid state");
|
||||
}
|
||||
MOZ_ASSERT(mAgents.Contains(aParent));
|
||||
|
||||
// We need to keep the array alive for the life-time of this operation.
|
||||
nsTArray<RefPtr<BlobImpl>> blobs;
|
||||
@ -118,12 +101,13 @@ BroadcastChannelService::PostMessage(BroadcastChannelParent* aParent,
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < parents->Length(); ++i) {
|
||||
BroadcastChannelParent* parent = parents->ElementAt(i);
|
||||
for (auto iter = mAgents.Iter(); !iter.Done(); iter.Next()) {
|
||||
BroadcastChannelParent* parent = iter.Get()->GetKey();
|
||||
MOZ_ASSERT(parent);
|
||||
|
||||
if (parent != aParent) {
|
||||
parent->Deliver(aData);
|
||||
parent->CheckAndDeliver(aData, PromiseFlatCString(aOrigin),
|
||||
PromiseFlatString(aChannel), aPrivateBrowsing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include "nsISupportsImpl.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsTHashtable.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#undef PostMessage
|
||||
@ -28,22 +28,20 @@ public:
|
||||
|
||||
static already_AddRefed<BroadcastChannelService> GetOrCreate();
|
||||
|
||||
void RegisterActor(BroadcastChannelParent* aParent,
|
||||
const nsAString& aOriginChannelKey);
|
||||
void UnregisterActor(BroadcastChannelParent* aParent,
|
||||
const nsAString& aOriginChannelKey);
|
||||
void RegisterActor(BroadcastChannelParent* aParent);
|
||||
void UnregisterActor(BroadcastChannelParent* aParent);
|
||||
|
||||
void PostMessage(BroadcastChannelParent* aParent,
|
||||
const ClonedMessageData& aData,
|
||||
const nsAString& aOriginChannelKey);
|
||||
const nsACString& aOrigin,
|
||||
const nsAString& aChannel,
|
||||
bool aPrivateBrowsing);
|
||||
|
||||
private:
|
||||
BroadcastChannelService();
|
||||
~BroadcastChannelService();
|
||||
|
||||
// Raw Pointers because the actors keep alive this service.
|
||||
nsDataHashtable<nsStringHashKey,
|
||||
nsTArray<BroadcastChannelParent*>*> mAgents;
|
||||
nsTHashtable<nsPtrHashKey<BroadcastChannelParent>> mAgents;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -25,4 +25,3 @@ skip-if = buildapp != 'mulet'
|
||||
skip-if = buildapp != 'mulet'
|
||||
[test_bfcache.html]
|
||||
[test_invalidState.html]
|
||||
[test_ordering.html]
|
||||
|
@ -1,65 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for BroadcastChannel.postMessage invalid State</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="content"></div>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
let c1 = new BroadcastChannel('order');
|
||||
let c2 = new BroadcastChannel('order');
|
||||
let c3 = new BroadcastChannel('order');
|
||||
|
||||
let events = [];
|
||||
let doneCount = 0;
|
||||
|
||||
function whichBC(bc) {
|
||||
if (bc == c1) return "c1";
|
||||
if (bc == c2) return "c2";
|
||||
if (bc == c3) return "c3";
|
||||
return "What?!?";
|
||||
}
|
||||
|
||||
function handler(e) {
|
||||
events.push(e);
|
||||
if (e.data == 'done') {
|
||||
doneCount++;
|
||||
if (doneCount == 2) {
|
||||
is(events.length, 6, "Correct length");
|
||||
is(whichBC(events[0].target), "c2", 'target for event 0');
|
||||
is(events[0].data, 'from c1');
|
||||
is(whichBC(events[1].target), "c3", 'target for event 1');
|
||||
is(events[1].data, 'from c1');
|
||||
is(whichBC(events[2].target), "c1", 'target for event 2');
|
||||
is(events[2].data, 'from c3');
|
||||
is(whichBC(events[3].target), "c2", 'target for event 3');
|
||||
is(events[3].data, 'from c3');
|
||||
is(whichBC(events[4].target), "c1", 'target for event 4');
|
||||
is(events[4].data, 'done');
|
||||
is(whichBC(events[5].target), "c3", 'target for event 5');
|
||||
is(events[5].data, 'done');
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c1.onmessage = handler;
|
||||
c2.onmessage = handler;
|
||||
c3.onmessage = handler;
|
||||
|
||||
c1.postMessage('from c1');
|
||||
c3.postMessage('from c3');
|
||||
c2.postMessage('done');
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -471,22 +471,7 @@ BackgroundParentImpl::AllocPBroadcastChannelParent(
|
||||
AssertIsInMainProcess();
|
||||
AssertIsOnBackgroundThread();
|
||||
|
||||
nsString originChannelKey;
|
||||
|
||||
// The format of originChannelKey is:
|
||||
// <channelName>|pb={true,false}|<origin+OriginAttributes>
|
||||
|
||||
originChannelKey.Assign(aChannel);
|
||||
|
||||
if (aPrivateBrowsing) {
|
||||
originChannelKey.AppendLiteral("|pb=true|");
|
||||
} else {
|
||||
originChannelKey.AppendLiteral("|pb=false|");
|
||||
}
|
||||
|
||||
originChannelKey.Append(NS_ConvertUTF8toUTF16(aOrigin));
|
||||
|
||||
return new BroadcastChannelParent(originChannelKey);
|
||||
return new BroadcastChannelParent(aOrigin, aChannel, aPrivateBrowsing);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
Loading…
x
Reference in New Issue
Block a user