From 9a3e22bc9c309807858e0675203036c5ef5a44ab Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 14 Jan 2015 11:50:34 +0000 Subject: [PATCH] Bug 966439 - BroadcastChannel API - patch 2 - close() method, r=smaug --- dom/broadcastchannel/BroadcastChannel.cpp | 41 ++++++++++++- dom/broadcastchannel/BroadcastChannel.h | 12 +++- dom/broadcastchannel/tests/mochitest.ini | 1 + .../tests/test_broadcastchannel_close.html | 58 +++++++++++++++++++ dom/webidl/BroadcastChannel.webidl | 3 + 5 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 dom/broadcastchannel/tests/test_broadcastchannel_close.html diff --git a/dom/broadcastchannel/BroadcastChannel.cpp b/dom/broadcastchannel/BroadcastChannel.cpp index 09b2f9793220..f65fe2b45a55 100644 --- a/dom/broadcastchannel/BroadcastChannel.cpp +++ b/dom/broadcastchannel/BroadcastChannel.cpp @@ -219,6 +219,7 @@ BroadcastChannel::BroadcastChannel(nsPIDOMWindow* aWindow, , mChannel(aChannel) , mIsKeptAlive(false) , mInnerID(0) + , mState(StateActive) { // Window can be null in workers } @@ -322,7 +323,18 @@ BroadcastChannel::Constructor(const GlobalObject& aGlobal, } void -BroadcastChannel::PostMessage(const nsAString& aMessage) +BroadcastChannel::PostMessage(const nsAString& aMessage, ErrorResult& aRv) +{ + if (mState != StateActive) { + aRv.Throw(NS_ERROR_FAILURE); + return; + } + + PostMessageInternal(aMessage); +} + +void +BroadcastChannel::PostMessageInternal(const nsAString& aMessage) { if (mActor) { nsRefPtr runnable = @@ -338,6 +350,21 @@ BroadcastChannel::PostMessage(const nsAString& aMessage) mPendingMessages.AppendElement(aMessage); } +void +BroadcastChannel::Close() +{ + if (mState != StateActive) { + return; + } + + if (mPendingMessages.IsEmpty()) { + Shutdown(); + } else { + MOZ_ASSERT(!mActor); + mState = StateClosing; + } +} + void BroadcastChannel::ActorFailed() { @@ -349,6 +376,10 @@ BroadcastChannel::ActorCreated(ipc::PBackgroundChild* aActor) { MOZ_ASSERT(aActor); + if (mState == StateClosed) { + return; + } + PBroadcastChannelChild* actor = aActor->SendPBroadcastChannelConstructor(mPrincipalInfo, mOrigin, mChannel); @@ -359,15 +390,21 @@ BroadcastChannel::ActorCreated(ipc::PBackgroundChild* aActor) // Flush pending messages. for (uint32_t i = 0; i < mPendingMessages.Length(); ++i) { - PostMessage(mPendingMessages[i]); + PostMessageInternal(mPendingMessages[i]); } mPendingMessages.Clear(); + + if (mState == StateClosing) { + Shutdown(); + } } void BroadcastChannel::Shutdown() { + mState = StateClosed; + // If shutdown() is called we have to release the reference if we still keep // it. if (mIsKeptAlive) { diff --git a/dom/broadcastchannel/BroadcastChannel.h b/dom/broadcastchannel/BroadcastChannel.h index 71ebd9d5cf91..ea4656ea38bb 100644 --- a/dom/broadcastchannel/BroadcastChannel.h +++ b/dom/broadcastchannel/BroadcastChannel.h @@ -53,7 +53,9 @@ public: aName = mChannel; } - void PostMessage(const nsAString& aMessage); + void PostMessage(const nsAString& aMessage, ErrorResult& aRv); + + void Close(); EventHandlerNonNull* GetOnmessage(); void SetOnmessage(EventHandlerNonNull* aCallback); @@ -81,6 +83,8 @@ private: ~BroadcastChannel(); + void PostMessageInternal(const nsAString& aMessage); + void UpdateMustKeepAlive(); nsRefPtr mActor; @@ -95,6 +99,12 @@ private: bool mIsKeptAlive; uint64_t mInnerID; + + enum { + StateActive, + StateClosing, + StateClosed + } mState; }; } // namespace dom diff --git a/dom/broadcastchannel/tests/mochitest.ini b/dom/broadcastchannel/tests/mochitest.ini index 1218751c07ff..5d5aa5bf0099 100644 --- a/dom/broadcastchannel/tests/mochitest.ini +++ b/dom/broadcastchannel/tests/mochitest.ini @@ -6,3 +6,4 @@ support-files = [test_broadcastchannel_basic.html] [test_broadcastchannel_self.html] [test_broadcastchannel_worker.html] +[test_broadcastchannel_close.html] diff --git a/dom/broadcastchannel/tests/test_broadcastchannel_close.html b/dom/broadcastchannel/tests/test_broadcastchannel_close.html new file mode 100644 index 000000000000..72b252015e8a --- /dev/null +++ b/dom/broadcastchannel/tests/test_broadcastchannel_close.html @@ -0,0 +1,58 @@ + + + + Test for BroadcastChannel + + + + + +
+ + + + diff --git a/dom/webidl/BroadcastChannel.webidl b/dom/webidl/BroadcastChannel.webidl index 2d611bb0328f..2d128c6a02e5 100644 --- a/dom/webidl/BroadcastChannel.webidl +++ b/dom/webidl/BroadcastChannel.webidl @@ -12,7 +12,10 @@ interface BroadcastChannel : EventTarget { readonly attribute DOMString name; + [Throws] void postMessage(DOMString message); + void close(); + attribute EventHandler onmessage; };