Bug 966439 - BroadcastChannel API - patch 8 - Async BC.close(), r=bent

This commit is contained in:
Andrea Marchesini 2015-01-15 16:58:42 +00:00
parent f2a06f382f
commit 11e0a4cab1
3 changed files with 56 additions and 5 deletions

View File

@ -232,6 +232,37 @@ private:
NS_IMPL_ISUPPORTS(PostMessageRunnable, nsICancelableRunnable, nsIRunnable)
class CloseRunnable MOZ_FINAL : public nsICancelableRunnable
{
public:
NS_DECL_ISUPPORTS
CloseRunnable(BroadcastChannel* aBC)
: mBC(aBC)
{
MOZ_ASSERT(mBC);
}
NS_IMETHODIMP Run()
{
mBC->Shutdown();
return NS_OK;
}
NS_IMETHODIMP Cancel()
{
mBC = nullptr;
return NS_OK;
}
private:
~CloseRunnable() {}
nsRefPtr<BroadcastChannel> mBC;
};
NS_IMPL_ISUPPORTS(CloseRunnable, nsICancelableRunnable, nsIRunnable)
class TeardownRunnable MOZ_FINAL : public nsICancelableRunnable
{
public:
@ -480,7 +511,12 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal,
new BroadcastChannel(window, principalInfo, origin, aChannel);
// Register this component to PBackground.
ipc::BackgroundChild::GetOrCreateForCurrentThread(bc);
PBackgroundChild* actor = BackgroundChild::GetForCurrentThread();
if (actor) {
bc->ActorCreated(actor);
} else {
BackgroundChild::GetOrCreateForCurrentThread(bc);
}
if (!workerPrivate) {
MOZ_ASSERT(window);
@ -556,7 +592,16 @@ BroadcastChannel::Close()
}
if (mPendingMessages.IsEmpty()) {
Shutdown();
// We cannot call Shutdown() immediatelly because we could have some
// postMessage runnable already dispatched. Instead, we change the state to
// StateClosed and we shutdown the actor asynchrounsly.
mState = StateClosed;
nsRefPtr<CloseRunnable> runnable = new CloseRunnable(this);
if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
NS_WARNING("Failed to dispatch to the current thread!");
}
} else {
MOZ_ASSERT(!mActor);
mState = StateClosing;
@ -570,7 +615,7 @@ BroadcastChannel::ActorFailed()
}
void
BroadcastChannel::ActorCreated(ipc::PBackgroundChild* aActor)
BroadcastChannel::ActorCreated(PBackgroundChild* aActor)
{
MOZ_ASSERT(aActor);

View File

@ -79,6 +79,11 @@ public:
void Shutdown();
bool IsClosed() const
{
return mState != StateActive;
}
private:
BroadcastChannel(nsPIDOMWindow* aWindow,
const PrincipalInfo& aPrincipalInfo,

View File

@ -44,8 +44,9 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
nsCOMPtr<DOMEventTargetHelper> helper = mBC;
nsCOMPtr<EventTarget> eventTarget = do_QueryInterface(helper);
// This object is going to be deleted soon. No notify is required.
if (!eventTarget) {
// This object has been already closed by content or is going to be deleted
// soon. No notify is required.
if (!eventTarget || mBC->IsClosed()) {
return true;
}