Backed out changeset f527785e39c6 (bug 1215092)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Wed, 28 Oct 2015 14:28:35 +0100
changeset 305157 fbd7ac7ed4f69be02a444cd895472238a19505b9
parent 305156 0fa26a79f3f6e69dc881a4f95f2005d514f493f5
child 305158 929a872c1f15ef81d7730d366d95983b2e287602
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1215092
milestone44.0a1
backs outf527785e39c64e2d33b9606275bf2a04015f739c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset f527785e39c6 (bug 1215092)
dom/base/WebSocket.cpp
dom/base/test/test_websocket_frame.html
netwerk/protocol/websocket/PWebSocketEventListener.ipdl
netwerk/protocol/websocket/WebSocketEventListenerChild.cpp
netwerk/protocol/websocket/WebSocketEventListenerChild.h
netwerk/protocol/websocket/WebSocketEventListenerParent.cpp
netwerk/protocol/websocket/WebSocketEventService.cpp
netwerk/protocol/websocket/WebSocketEventService.h
netwerk/protocol/websocket/nsIWebSocketChannel.idl
netwerk/protocol/websocket/nsIWebSocketEventService.idl
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -32,17 +32,16 @@
 #include "nsIUnicodeEncoder.h"
 #include "nsThreadUtils.h"
 #include "nsIPromptFactory.h"
 #include "nsIWindowWatcher.h"
 #include "nsIPrompt.h"
 #include "nsIStringBundle.h"
 #include "nsIConsoleService.h"
 #include "mozilla/dom/CloseEvent.h"
-#include "mozilla/net/WebSocketEventService.h"
 #include "nsICryptoHash.h"
 #include "nsJSUtils.h"
 #include "nsIScriptError.h"
 #include "nsNetUtil.h"
 #include "nsIAuthPrompt.h"
 #include "nsIAuthPrompt2.h"
 #include "nsILoadGroup.h"
 #include "mozilla/Preferences.h"
@@ -236,18 +235,16 @@ public:
   nsWeakPtr mWeakLoadGroup;
 
   bool mIsMainThread;
 
   // This mutex protects mWorkerShuttingDown.
   mozilla::Mutex mMutex;
   bool mWorkerShuttingDown;
 
-  RefPtr<WebSocketEventService> mService;
-
 private:
   ~WebSocketImpl()
   {
     // If we threw during Init we never called disconnect
     if (!mDisconnectingOrDisconnected) {
       Disconnect();
     }
   }
@@ -628,18 +625,21 @@ WebSocketImpl::Disconnect()
       new DisconnectInternalRunnable(this);
     runnable->Dispatch(mWorkerPrivate->GetJSContext());
   }
 
   // DontKeepAliveAnyMore() can release the object. So hold a reference to this
   // until the end of the method.
   RefPtr<WebSocketImpl> kungfuDeathGrip = this;
 
-  NS_ReleaseOnMainThread(mChannel);
-  NS_ReleaseOnMainThread(static_cast<nsIWebSocketEventService*>(mService.forget().take()));
+  nsCOMPtr<nsIThread> mainThread;
+  if (NS_FAILED(NS_GetMainThread(getter_AddRefs(mainThread))) ||
+      NS_FAILED(NS_ProxyRelease(mainThread, mChannel))) {
+    NS_WARNING("Failed to proxy release of channel, leaking instead!");
+  }
 
   mWebSocket->DontKeepAliveAnyMore();
   mWebSocket->mImpl = nullptr;
 
   if (mWorkerPrivate && mWorkerFeature) {
     UnregisterFeature();
   }
 
@@ -764,21 +764,16 @@ WebSocketImpl::OnStart(nsISupports* aCon
     mChannel->GetProtocol(mWebSocket->mEstablishedProtocol);
   }
 
   mChannel->GetExtensions(mWebSocket->mEstablishedExtensions);
   UpdateURI();
 
   mWebSocket->SetReadyState(WebSocket::OPEN);
 
-  mService->WebSocketOpened(mChannel->Serial(),mInnerWindowID,
-                            mWebSocket->mEffectiveURL,
-                            mWebSocket->mEstablishedProtocol,
-                            mWebSocket->mEstablishedExtensions);
-
   // Let's keep the object alive because the webSocket can be CCed in the
   // onopen callback.
   RefPtr<WebSocket> webSocket = mWebSocket;
 
   // Call 'onopen'
   rv = webSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open"));
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the open event");
@@ -1359,22 +1354,16 @@ WebSocket::Constructor(const GlobalObjec
 
   // It can be that we have been already disconnected because the WebSocket is
   // gone away while we where initializing the webSocket.
   if (!webSocket->mImpl) {
     aRv.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
 
-  // Let's inform devtools about this new active WebSocket.
-  webSocket->mImpl->mService->WebSocketCreated(webSocket->mImpl->mChannel->Serial(),
-                                               webSocket->mImpl->mInnerWindowID,
-                                               webSocket->mURI,
-                                               webSocket->mImpl->mRequestedProtocolList);
-
   cws.Done();
   return webSocket.forget();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(WebSocket)
 
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(WebSocket)
   bool isBlack = tmp->IsBlack();
@@ -1450,18 +1439,16 @@ WebSocketImpl::Init(JSContext* aCx,
                     uint32_t aScriptLine,
                     uint32_t aScriptColumn,
                     ErrorResult& aRv,
                     bool* aConnectionFailed)
 {
   AssertIsOnMainThread();
   MOZ_ASSERT(aPrincipal);
 
-  mService = WebSocketEventService::GetOrCreate();
-
   // We need to keep the implementation alive in case the init disconnects it
   // because of some error.
   RefPtr<WebSocketImpl> kungfuDeathGrip = this;
 
   // Attempt to kill "ghost" websocket: but usually too early for check to fail
   aRv = mWebSocket->CheckInnerWindowCorrectness();
   if (NS_WARN_IF(aRv.Failed())) {
     return;
@@ -1666,18 +1653,16 @@ WebSocketImpl::AsyncOpen(nsIPrincipal* a
   nsCOMPtr<nsIURI> uri;
   aRv = NS_NewURI(getter_AddRefs(uri), mURI);
   MOZ_ASSERT(!aRv.Failed());
 
   aRv = mChannel->AsyncOpen(uri, asciiOrigin, aInnerWindowID, this, nullptr);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
-
-  mInnerWindowID = aInnerWindowID;
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketImpl methods:
 //-----------------------------------------------------------------------------
 
 class nsAutoCloseWS final
 {
@@ -1893,25 +1878,21 @@ WebSocket::CreateAndDispatchMessageEvent
 
   return DispatchDOMEvent(nullptr, static_cast<Event*>(event), nullptr,
                           nullptr);
 }
 
 nsresult
 WebSocket::CreateAndDispatchCloseEvent(bool aWasClean,
                                        uint16_t aCode,
-                                       const nsAString& aReason)
+                                       const nsAString &aReason)
 {
   MOZ_ASSERT(mImpl);
   AssertIsOnTargetThread();
 
-  mImpl->mService->WebSocketClosed(mImpl->mChannel->Serial(),
-                                   mImpl->mInnerWindowID,
-                                   aWasClean, aCode, aReason);
-
   nsresult rv = CheckInnerWindowCorrectness();
   if (NS_FAILED(rv)) {
     return NS_OK;
   }
 
   CloseEventInit init;
   init.mBubbles = false;
   init.mCancelable = false;
--- a/dom/base/test/test_websocket_frame.html
+++ b/dom/base/test/test_websocket_frame.html
@@ -7,23 +7,18 @@
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
 </head>
 <body>
 <script class="testbody" type="text/javascript">
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
-const URI = "ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic";
-
 var frameReceivedCounter = 0;
 var frameSentCounter = 0;
-var webSocketCreatedCounter = 0;
-var webSocketOpenedCounter = 0;
-var webSocketClosedCounter = 0;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 var tests = [
   { payload: "Hello world!" },
   { payload: (function() { var buffer = ""; for (var i = 0; i < 120; ++i) buffer += i; return buffer; }()) },
   { payload: "end" },
 ]
@@ -35,47 +30,16 @@ ok(innerId, "We have a valid innerWindow
 
 var service = Cc["@mozilla.org/websocketevent/service;1"]
                 .getService(Ci.nsIWebSocketEventService);
 ok(!!service, "We have the nsIWebSocketEventService");
 
 var listener = {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebSocketEventListener]),
 
-  webSocketCreated: function(aWebSocketSerialID, aURI, aProtocols) {
-    info("WebSocketCreated");
-
-    is(aURI, URI, "URI matches");
-    is(aProtocols, "frame", "Protocol matches");
-
-    webSocketCreatedCounter++;
-  },
-
-  webSocketOpened: function(aWebSocketSerialID, aEffectiveURI, aProtocols, aExtensions) {
-    info("WebSocketOpened");
-
-    is(aEffectiveURI, URI, "EffectiveURI matches");
-    is(aProtocols, "frame", "Protocol matches");
-    is(aExtensions, "permessage-deflate", "No extensions");
-
-    webSocketOpenedCounter++;
-  },
-
-  webSocketClosed: function(aWebSocketSerialID, aWasClean,
-                            aCode, aReason) {
-    info("WebSocketClosed");
-
-    ok(aWasClean, "The socket is closed in a clean state");
-    is(aCode, 1000, "Exit code 1000");
-    ok(!aReason.length, "No reason");
-
-    webSocketClosedCounter++;
-    checkListener();
-  },
-
   frameReceived: function(aWebSocketSerialID, aFrame) {
     ok(!!aFrame, "We have received a frame");
 
     if (tests.length) {
       ok(aFrame.timeStamp, "Checking timeStamp: " + aFrame.timeStamp);
       is(aFrame.finBit, true, "Checking finBit");
       is(aFrame.rsvBit1, true, "Checking rsvBit1");
       is(aFrame.rsvBit2, false, "Checking rsvBit2");
@@ -129,31 +93,31 @@ var listener = {
 service.addListener(innerId, listener);
 ok(true, "Listener added");
 
 function checkListener() {
   service.removeListener(innerId, listener);
 
   ok(frameReceivedCounter, "We received some frames!");
   ok(frameSentCounter, "We sent some frames!");
-  ok(webSocketCreatedCounter, "We have a create notification");
-  ok(webSocketOpenedCounter, "We have a open notification");
-  ok(webSocketClosedCounter, "We have a close notification");
   SimpleTest.finish();
 }
 
-var ws = new WebSocket(URI, "frame");
+var ws = new WebSocket("ws://mochi.test:8888/tests/dom/base/test/file_websocket_basic", "frame");
 ws.onopen = function(e) {
   info("onopen");
 
   ws.send(tests[0].payload);
 }
 
 ws.onclose = function(e) {
   info("onclose");
+
+  ws.close();
+  checkListener();
 }
 
 ws.onmessage = function(e) {
   info("onmessage");
 
   is(e.data, tests[0].payload, "Wrong data");
   tests.shift();
   if (tests.length) {
--- a/netwerk/protocol/websocket/PWebSocketEventListener.ipdl
+++ b/netwerk/protocol/websocket/PWebSocketEventListener.ipdl
@@ -12,30 +12,16 @@ using mozilla::net::WebSocketFrameData f
 namespace mozilla {
 namespace net {
 
 async protocol PWebSocketEventListener
 {
   manager PNecko;
 
 child:
-  WebSocketCreated(uint32_t awebSocketSerialID,
-                   nsString aURI,
-                   nsCString aProtocols);
-
-  WebSocketOpened(uint32_t awebSocketSerialID,
-                  nsString aEffectiveURI,
-                  nsCString aProtocols,
-                  nsCString aExtensions);
-
-  WebSocketClosed(uint32_t awebSocketSerialID,
-                  bool aWasClean,
-                  uint16_t aCode,
-                  nsString aReason);
-
   FrameReceived(uint32_t aWebSocketSerialID,
                 WebSocketFrameData aFrameData);
 
   FrameSent(uint32_t aWebSocketSerialID,
             WebSocketFrameData aFrameData);
 
   __delete__();
 
--- a/netwerk/protocol/websocket/WebSocketEventListenerChild.cpp
+++ b/netwerk/protocol/websocket/WebSocketEventListenerChild.cpp
@@ -18,57 +18,16 @@ WebSocketEventListenerChild::WebSocketEv
 {}
 
 WebSocketEventListenerChild::~WebSocketEventListenerChild()
 {
   MOZ_ASSERT(!mService);
 }
 
 bool
-WebSocketEventListenerChild::RecvWebSocketCreated(const uint32_t& aWebSocketSerialID,
-                                                  const nsString& aURI,
-                                                  const nsCString& aProtocols)
-{
-  if (mService) {
-    mService->WebSocketCreated(aWebSocketSerialID, mInnerWindowID, aURI,
-                               aProtocols);
-  }
-
-  return true;
-}
-
-bool
-WebSocketEventListenerChild::RecvWebSocketOpened(const uint32_t& aWebSocketSerialID,
-                                                 const nsString& aEffectiveURI,
-                                                 const nsCString& aProtocols,
-                                                 const nsCString& aExtensions)
-{
-  if (mService) {
-    mService->WebSocketOpened(aWebSocketSerialID, mInnerWindowID,
-                              aEffectiveURI, aProtocols, aExtensions);
-  }
-
-  return true;
-}
-
-bool
-WebSocketEventListenerChild::RecvWebSocketClosed(const uint32_t& aWebSocketSerialID,
-                                                 const bool& aWasClean,
-                                                 const uint16_t& aCode,
-                                                 const nsString& aReason)
-{
-  if (mService) {
-    mService->WebSocketClosed(aWebSocketSerialID, mInnerWindowID,
-                              aWasClean, aCode, aReason);
-  }
-
-  return true;
-}
-
-bool
 WebSocketEventListenerChild::RecvFrameReceived(const uint32_t& aWebSocketSerialID,
                                                const WebSocketFrameData& aFrameData)
 {
   if (mService) {
     RefPtr<WebSocketFrame> frame = new WebSocketFrame(aFrameData);
     mService->FrameReceived(aWebSocketSerialID, mInnerWindowID, frame);
   }
 
--- a/netwerk/protocol/websocket/WebSocketEventListenerChild.h
+++ b/netwerk/protocol/websocket/WebSocketEventListenerChild.h
@@ -16,30 +16,16 @@ class WebSocketEventService;
 
 class WebSocketEventListenerChild final : public PWebSocketEventListenerChild
 {
 public:
   NS_INLINE_DECL_REFCOUNTING(WebSocketEventListenerChild)
 
   explicit WebSocketEventListenerChild(uint64_t aInnerWindowID);
 
-  bool RecvWebSocketCreated(const uint32_t& aWebSocketSerialID,
-                            const nsString& aURI,
-                            const nsCString& aProtocols) override;
-
-  bool RecvWebSocketOpened(const uint32_t& aWebSocketSerialID,
-                           const nsString& aEffectiveURI,
-                           const nsCString& aProtocols,
-                           const nsCString& aExtensions) override;
-
-  bool RecvWebSocketClosed(const uint32_t& aWebSocketSerialID,
-                          const bool& aWasClean,
-                          const uint16_t& aCode,
-                          const nsString& aReason) override;
-
   bool RecvFrameReceived(const uint32_t& aWebSocketSerialID,
                          const WebSocketFrameData& aFrameData) override;
 
   bool RecvFrameSent(const uint32_t& aWebSocketSerialID,
                      const WebSocketFrameData& aFrameData) override;
 
   void Close();
 
--- a/netwerk/protocol/websocket/WebSocketEventListenerParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketEventListenerParent.cpp
@@ -52,48 +52,16 @@ WebSocketEventListenerParent::Unregister
 {
   if (mService) {
     mService->RemoveListener(mInnerWindowID, this);
     mService = nullptr;
   }
 }
 
 NS_IMETHODIMP
-WebSocketEventListenerParent::WebSocketCreated(uint32_t aWebSocketSerialID,
-                                               const nsAString& aURI,
-                                               const nsACString& aProtocols)
-{
-  unused << SendWebSocketCreated(aWebSocketSerialID, nsString(aURI),
-                                 nsCString(aProtocols));
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-WebSocketEventListenerParent::WebSocketOpened(uint32_t aWebSocketSerialID,
-                                              const nsAString& aEffectiveURI,
-                                              const nsACString& aProtocols,
-                                              const nsACString& aExtensions)
-{
-  unused << SendWebSocketOpened(aWebSocketSerialID, nsString(aEffectiveURI),
-                                nsCString(aProtocols), nsCString(aExtensions));
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-WebSocketEventListenerParent::WebSocketClosed(uint32_t aWebSocketSerialID,
-                                              bool aWasClean,
-                                              uint16_t aCode,
-                                              const nsAString& aReason)
-{
-  unused << SendWebSocketClosed(aWebSocketSerialID, aWasClean, aCode,
-                                nsString(aReason));
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 WebSocketEventListenerParent::FrameReceived(uint32_t aWebSocketSerialID,
                                             nsIWebSocketFrame* aFrame)
 {
   if (!aFrame) {
     return NS_ERROR_FAILURE;
   }
 
   WebSocketFrame* frame = static_cast<WebSocketFrame*>(aFrame);
--- a/netwerk/protocol/websocket/WebSocketEventService.cpp
+++ b/netwerk/protocol/websocket/WebSocketEventService.cpp
@@ -25,162 +25,71 @@ StaticRefPtr<WebSocketEventService> gWeb
 bool
 IsChildProcess()
 {
   return XRE_GetProcessType() != GeckoProcessType_Default;
 }
 
 } // anonymous namespace
 
-class WebSocketBaseRunnable : public nsRunnable
+class WebSocketFrameRunnable final : public nsRunnable
 {
 public:
-  WebSocketBaseRunnable(uint32_t aWebSocketSerialID,
-                        uint64_t aInnerWindowID)
+  WebSocketFrameRunnable(uint32_t aWebSocketSerialID,
+                         uint64_t aInnerWindowID,
+                         WebSocketFrame* aFrame,
+                         bool aFrameSent)
     : mWebSocketSerialID(aWebSocketSerialID)
     , mInnerWindowID(aInnerWindowID)
+    , mFrame(aFrame)
+    , mFrameSent(aFrameSent)
   {}
 
   NS_IMETHOD Run() override
   {
     MOZ_ASSERT(NS_IsMainThread());
 
     RefPtr<WebSocketEventService> service = WebSocketEventService::GetOrCreate();
     MOZ_ASSERT(service);
 
-    WebSocketEventService::WindowListeners listeners;
-    service->GetListeners(mInnerWindowID, listeners);
+    WebSocketEventService::WindowListeners* listeners =
+      service->GetListeners(mInnerWindowID);
+    if (!listeners) {
+      return NS_OK;
+    }
 
-    for (uint32_t i = 0; i < listeners.Length(); ++i) {
-      DoWork(listeners[i]);
+    nsresult rv;
+    WebSocketEventService::WindowListeners::ForwardIterator iter(*listeners);
+    while (iter.HasMore()) {
+      nsCOMPtr<nsIWebSocketEventListener> listener = iter.GetNext();
+
+      if (mFrameSent) {
+        rv = listener->FrameSent(mWebSocketSerialID, mFrame);
+      } else {
+        rv = listener->FrameReceived(mWebSocketSerialID, mFrame);
+      }
+
+      NS_WARN_IF(NS_FAILED(rv));
     }
 
     return NS_OK;
   }
 
 protected:
-  ~WebSocketBaseRunnable()
+  ~WebSocketFrameRunnable()
   {}
 
-  virtual void DoWork(nsIWebSocketEventListener* aListener) = 0;
-
   uint32_t mWebSocketSerialID;
   uint64_t mInnerWindowID;
-};
-
-class WebSocketFrameRunnable final : public WebSocketBaseRunnable
-{
-public:
-  WebSocketFrameRunnable(uint32_t aWebSocketSerialID,
-                         uint64_t aInnerWindowID,
-                         WebSocketFrame* aFrame,
-                         bool aFrameSent)
-    : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
-    , mFrame(aFrame)
-    , mFrameSent(aFrameSent)
-  {}
-
-private:
-  virtual void DoWork(nsIWebSocketEventListener* aListener) override
-  {
-    nsresult rv;
-
-    if (mFrameSent) {
-      rv = aListener->FrameSent(mWebSocketSerialID, mFrame);
-    } else {
-      rv = aListener->FrameReceived(mWebSocketSerialID, mFrame);
-    }
-
-    NS_WARN_IF(NS_FAILED(rv));
-  }
 
   RefPtr<WebSocketFrame> mFrame;
+
   bool mFrameSent;
 };
 
-class WebSocketCreatedRunnable final : public WebSocketBaseRunnable
-{
-public:
-  WebSocketCreatedRunnable(uint32_t aWebSocketSerialID,
-                           uint64_t aInnerWindowID,
-                           const nsAString& aURI,
-                           const nsACString& aProtocols)
-    : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
-    , mURI(aURI)
-    , mProtocols(aProtocols)
-  {}
-
-private:
-  virtual void DoWork(nsIWebSocketEventListener* aListener) override
-  {
-    nsresult rv = aListener->WebSocketCreated(mWebSocketSerialID,
-                                             mURI, mProtocols);
-    NS_WARN_IF(NS_FAILED(rv));
-  }
-
-  const nsString mURI;
-  const nsCString mProtocols;
-};
-
-class WebSocketOpenedRunnable final : public WebSocketBaseRunnable
-{
-public:
-  WebSocketOpenedRunnable(uint32_t aWebSocketSerialID,
-                           uint64_t aInnerWindowID,
-                           const nsAString& aEffectiveURI,
-                           const nsACString& aProtocols,
-                           const nsACString& aExtensions)
-    : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
-    , mEffectiveURI(aEffectiveURI)
-    , mProtocols(aProtocols)
-    , mExtensions(aExtensions)
-  {}
-
-private:
-  virtual void DoWork(nsIWebSocketEventListener* aListener) override
-  {
-    nsresult rv = aListener->WebSocketOpened(mWebSocketSerialID,
-                                             mEffectiveURI,
-                                             mProtocols,
-                                             mExtensions);
-    NS_WARN_IF(NS_FAILED(rv));
-  }
-
-  const nsString mEffectiveURI;
-  const nsCString mProtocols;
-  const nsCString mExtensions;
-};
-
-class WebSocketClosedRunnable final : public WebSocketBaseRunnable
-{
-public:
-  WebSocketClosedRunnable(uint32_t aWebSocketSerialID,
-                          uint64_t aInnerWindowID,
-                          bool aWasClean,
-                          uint16_t aCode,
-                          const nsAString& aReason)
-    : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID)
-    , mWasClean(aWasClean)
-    , mCode(aCode)
-    , mReason(aReason)
-  {}
-
-private:
-  virtual void DoWork(nsIWebSocketEventListener* aListener) override
-  {
-    nsresult rv = aListener->WebSocketClosed(mWebSocketSerialID,
-                                             mWasClean, mCode, mReason);
-    NS_WARN_IF(NS_FAILED(rv));
-  }
-
-  bool mWasClean;
-  uint16_t mCode;
-  const nsString mReason;
-};
-
 /* static */ already_AddRefed<WebSocketEventService>
 WebSocketEventService::GetOrCreate()
 {
   MOZ_ASSERT(NS_IsMainThread());
 
   if (!gWebSocketEventService) {
     gWebSocketEventService = new WebSocketEventService();
   }
@@ -211,72 +120,16 @@ WebSocketEventService::WebSocketEventSer
 }
 
 WebSocketEventService::~WebSocketEventService()
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 void
-WebSocketEventService::WebSocketCreated(uint32_t aWebSocketSerialID,
-                                        uint64_t aInnerWindowID,
-                                        const nsAString& aURI,
-                                        const nsACString& aProtocols)
-{
-  // Let's continue only if we have some listeners.
-  if (!HasListeners()) {
-    return;
-  }
-
-  RefPtr<WebSocketCreatedRunnable> runnable =
-    new WebSocketCreatedRunnable(aWebSocketSerialID, aInnerWindowID,
-                                 aURI, aProtocols);
-  nsresult rv = NS_DispatchToMainThread(runnable);
-  NS_WARN_IF(NS_FAILED(rv));
-}
-
-void
-WebSocketEventService::WebSocketOpened(uint32_t aWebSocketSerialID,
-                                       uint64_t aInnerWindowID,
-                                       const nsAString& aEffectiveURI,
-                                       const nsACString& aProtocols,
-                                       const nsACString& aExtensions)
-{
-  // Let's continue only if we have some listeners.
-  if (!HasListeners()) {
-    return;
-  }
-
-  RefPtr<WebSocketOpenedRunnable> runnable =
-    new WebSocketOpenedRunnable(aWebSocketSerialID, aInnerWindowID,
-                                aEffectiveURI, aProtocols, aExtensions);
-  nsresult rv = NS_DispatchToMainThread(runnable);
-  NS_WARN_IF(NS_FAILED(rv));
-}
-
-void
-WebSocketEventService::WebSocketClosed(uint32_t aWebSocketSerialID,
-                                       uint64_t aInnerWindowID,
-                                       bool aWasClean,
-                                       uint16_t aCode,
-                                       const nsAString& aReason)
-{
-  // Let's continue only if we have some listeners.
-  if (!HasListeners()) {
-    return;
-  }
-
-  RefPtr<WebSocketClosedRunnable> runnable =
-    new WebSocketClosedRunnable(aWebSocketSerialID, aInnerWindowID,
-                                aWasClean, aCode, aReason);
-  nsresult rv = NS_DispatchToMainThread(runnable);
-  NS_WARN_IF(NS_FAILED(rv));
-}
-
-void
 WebSocketEventService::FrameReceived(uint32_t aWebSocketSerialID,
                                      uint64_t aInnerWindowID,
                                      WebSocketFrame* aFrame)
 {
   MOZ_ASSERT(aFrame);
 
   // Let's continue only if we have some listeners.
   if (!HasListeners()) {
@@ -432,28 +285,21 @@ WebSocketEventService::Shutdown()
 }
 
 bool
 WebSocketEventService::HasListeners() const
 {
   return !!mCountListeners;
 }
 
-void
-WebSocketEventService::GetListeners(uint64_t aInnerWindowID,
-                                    WebSocketEventService::WindowListeners& aListeners) const
+WebSocketEventService::WindowListeners*
+WebSocketEventService::GetListeners(uint64_t aInnerWindowID) const
 {
-  aListeners.Clear();
-
   WindowListener* listener = mWindows.Get(aInnerWindowID);
-  if (!listener) {
-    return;
-  }
-
-  aListeners.AppendElements(listener->mListeners);
+  return listener ? &listener->mListeners : nullptr;
 }
 
 void
 WebSocketEventService::ShutdownActorListener(WindowListener* aListener)
 {
   MOZ_ASSERT(aListener);
   MOZ_ASSERT(aListener->mActor);
   aListener->mActor->Close();
--- a/netwerk/protocol/websocket/WebSocketEventService.h
+++ b/netwerk/protocol/websocket/WebSocketEventService.h
@@ -10,53 +10,36 @@
 #include "mozilla/Atomics.h"
 #include "nsIWebSocketEventService.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsIObserver.h"
 #include "nsISupportsImpl.h"
-#include "nsTArray.h"
+#include "nsTObserverArray.h"
 
 namespace mozilla {
 namespace net {
 
 class WebSocketFrame;
 class WebSocketEventListenerChild;
 
 class WebSocketEventService final : public nsIWebSocketEventService
                                   , public nsIObserver
 {
-  friend class WebSocketBaseRunnable;
+  friend class WebSocketFrameRunnable;
 
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
   NS_DECL_NSIWEBSOCKETEVENTSERVICE
 
   static already_AddRefed<WebSocketEventService> GetOrCreate();
 
-  void WebSocketCreated(uint32_t aWebSocketSerialID,
-                        uint64_t aInnerWindowID,
-                        const nsAString& aURI,
-                        const nsACString& aProtocols);
-
-  void WebSocketOpened(uint32_t aWebSocketSerialID,
-                       uint64_t aInnerWindowID,
-                       const nsAString& aEffectiveURI,
-                       const nsACString& aProtocols,
-                       const nsACString& aExtensions);
-
-  void WebSocketClosed(uint32_t aWebSocketSerialID,
-                       uint64_t aInnerWindowID,
-                       bool aWasClean,
-                       uint16_t aCode,
-                       const nsAString& aReason);
-
   void FrameReceived(uint32_t aWebSocketSerialID,
                      uint64_t aInnerWindowID,
                      WebSocketFrame* aFrame);
 
   void  FrameSent(uint32_t aWebSocketSerialID,
                   uint64_t aInnerWindowID,
                   WebSocketFrame* aFrame);
 
@@ -78,27 +61,25 @@ public:
 
 private:
   WebSocketEventService();
   ~WebSocketEventService();
 
   bool HasListeners() const;
   void Shutdown();
 
-  typedef nsTArray<nsCOMPtr<nsIWebSocketEventListener>> WindowListeners;
+  typedef nsTObserverArray<nsCOMPtr<nsIWebSocketEventListener>> WindowListeners;
 
   struct WindowListener
   {
     WindowListeners mListeners;
     RefPtr<WebSocketEventListenerChild> mActor;
   };
 
-  void GetListeners(uint64_t aInnerWindowID,
-                    WindowListeners& aListeners) const;
-
+  WindowListeners* GetListeners(uint64_t aInnerWindowID) const;
   void ShutdownActorListener(WindowListener* aListener);
 
   // Used only on the main-thread.
   nsClassHashtable<nsUint64HashKey, WindowListener> mWindows;
 
   Atomic<uint64_t> mCountListeners;
 };
 
--- a/netwerk/protocol/websocket/nsIWebSocketChannel.idl
+++ b/netwerk/protocol/websocket/nsIWebSocketChannel.idl
@@ -17,17 +17,17 @@ interface nsIPrincipal;
 
 /**
  * Low-level websocket API: handles network protocol.  
  *
  * This is primarly intended for use by the higher-level nsIWebSocket.idl.
  * We are also making it scriptable for now, but this may change once we have
  * WebSockets for Workers.
  */
-[scriptable, uuid(ce71d028-322a-4105-a947-a894689b52bf)]
+[scriptable, uuid(1bfc252b-ad46-413c-860b-2079bf1399c7)]
 interface nsIWebSocketChannel : nsISupports
 {
     /**
      * The original URI used to construct the protocol connection. This is used
      * in the case of a redirect or URI "resolution" (e.g. resolving a
      * resource: URI to a file: URI) so that the original pre-redirect
      * URI can still be obtained.  This is never null.
      */
@@ -223,21 +223,9 @@ interface nsIWebSocketChannel : nsISuppo
      */
     attribute unsigned long pingTimeout;
 
     /**
      * Unique ID for this channel. It's not readonly because when the channel is
      * created via IPC, the serial number is received from the child process.
      */
     attribute unsigned long serial;
-
-%{C++
-    inline uint32_t Serial()
-    {
-      uint32_t serial;
-      nsresult rv = GetSerial(&serial);
-      if (NS_WARN_IF(NS_FAILED(rv))) {
-        return 0;
-      }
-      return serial;
-    }
-%}
 };
--- a/netwerk/protocol/websocket/nsIWebSocketEventService.idl
+++ b/netwerk/protocol/websocket/nsIWebSocketEventService.idl
@@ -31,33 +31,19 @@ interface nsIWebSocketFrame : nsISupport
   const long OPCODE_BINARY       = 0x2;
 
   // Control opCode values:
   const long OPCODE_CLOSE        = 0x8;
   const long OPCODE_PING         = 0x9;
   const long OPCODE_PONG         = 0xA;
 };
 
-[scriptable, uuid(ccbd96ae-2b7d-42fc-9ee5-116fa8e1723a)]
+[scriptable, uuid(f6a7ec44-23b2-4c77-bb94-f11a8df5a874)]
 interface nsIWebSocketEventListener : nsISupports
 {
-  void webSocketCreated(in unsigned long aWebSocketSerialID,
-                        in AString aURI,
-                        in ACString aProtocols);
-
-  void webSocketOpened(in unsigned long aWebSocketSerialID,
-                       in AString aEffectiveURI,
-                       in ACString aProtocols,
-                       in ACString aExtensions);
-
-  void webSocketClosed(in unsigned long aWebSocketSerialID,
-                       in boolean aWasClean,
-                       in unsigned short aCode,
-                       in AString aReason);
-
   void frameReceived(in unsigned long aWebSocketSerialID,
                      in nsIWebSocketFrame aFrame);
 
   void frameSent(in unsigned long aWebSocketSerialID,
                  in nsIWebSocketFrame aFrame);
 };
 
 [scriptable, builtinclass, uuid(b89d1b90-2cf3-4d8f-ac21-5aedfb25c760)]