Backed out changeset fce8528ac1e2 (bug 1111971) for M-1/M-4 Test failures on a CLOSED TREE
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Fri, 09 Jan 2015 16:25:06 +0100
changeset 248851 b74c9afa3b4b8961134ecba62f1d36bb16c969ac
parent 248850 548ff18c9fc6a54dced7165f22f00ab803c746d2
child 248852 ca36fde7d91fac1ed3a64b48c3e7e0b89ae0ae3b
push id4489
push userraliiev@mozilla.com
push dateMon, 23 Feb 2015 15:17:55 +0000
treeherdermozilla-beta@fd7c3dc24146 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1111971
milestone37.0a1
backs outfce8528ac1e2385acd313595e52a4367cfd30ca8
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 fce8528ac1e2 (bug 1111971) for M-1/M-4 Test failures on a CLOSED TREE
dom/base/WebSocket.cpp
netwerk/protocol/websocket/WebSocketChannel.cpp
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -641,24 +641,23 @@ WebSocketImpl::DoOnMessageAvailable(cons
   }
 
   if (readyState == WebSocket::OPEN) {
     // Dispatch New Message
     nsresult rv = mWebSocket->CreateAndDispatchMessageEvent(aMsg, isBinary);
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to dispatch the message event");
     }
-
-    return NS_OK;
+  } else {
+    // CLOSING should be the only other state where it's possible to get msgs
+    // from channel: Spec says to drop them.
+    MOZ_ASSERT(readyState == WebSocket::CLOSING,
+               "Received message while CONNECTING or CLOSED");
   }
 
-  // CLOSING should be the only other state where it's possible to get msgs
-  // from channel: Spec says to drop them.
-  MOZ_ASSERT(readyState == WebSocket::CLOSING,
-             "Received message while CONNECTING or CLOSED");
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketImpl::OnMessageAvailable(nsISupports* aContext,
                                   const nsACString& aMsg)
 {
   AssertIsOnTargetThread();
@@ -714,27 +713,24 @@ WebSocketImpl::OnStart(nsISupports* aCon
     mChannel->GetProtocol(mWebSocket->mEstablishedProtocol);
   }
 
   mChannel->GetExtensions(mWebSocket->mEstablishedExtensions);
   UpdateURI();
 
   mWebSocket->SetReadyState(WebSocket::OPEN);
 
-  // Let's keep the object alive because the webSocket can be CCed in the
-  // onopen callback.
-  nsRefPtr<WebSocket> webSocket = mWebSocket;
-
   // Call 'onopen'
-  rv = webSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open"));
+  rv = mWebSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open"));
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the open event");
   }
 
-  webSocket->UpdateMustKeepAlive();
+  mWebSocket->UpdateMustKeepAlive();
+
   return NS_OK;
 }
 
 NS_IMETHODIMP
 WebSocketImpl::OnStop(nsISupports* aContext, nsresult aStatusCode)
 {
   AssertIsOnTargetThread();
 
@@ -1595,37 +1591,33 @@ WebSocketImpl::DispatchConnectionCloseEv
   AssertIsOnTargetThread();
 
   if (mDisconnectingOrDisconnected) {
     return;
   }
 
   mWebSocket->SetReadyState(WebSocket::CLOSED);
 
-  // Let's keep the object alive because the webSocket can be CCed in the
-  // onerror or in the onclose callback.
-  nsRefPtr<WebSocket> webSocket = mWebSocket;
-
   // Call 'onerror' if needed
   if (mFailed) {
     nsresult rv =
-      webSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
+      mWebSocket->CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
     if (NS_FAILED(rv)) {
       NS_WARNING("Failed to dispatch the error event");
     }
   }
 
-  nsresult rv = webSocket->CreateAndDispatchCloseEvent(mCloseEventWasClean,
-                                                       mCloseEventCode,
-                                                       mCloseEventReason);
+  nsresult rv = mWebSocket->CreateAndDispatchCloseEvent(mCloseEventWasClean,
+                                                        mCloseEventCode,
+                                                        mCloseEventReason);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the close event");
   }
 
-  webSocket->UpdateMustKeepAlive();
+  mWebSocket->UpdateMustKeepAlive();
   Disconnect();
 }
 
 nsresult
 WebSocket::CreateAndDispatchSimpleEvent(const nsAString& aName)
 {
   MOZ_ASSERT(mImpl);
   AssertIsOnTargetThread();
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -67,32 +67,16 @@
 // dupe one constant we need from it
 #define CLOSE_GOING_AWAY 1001
 
 extern PRThread *gSocketThread;
 
 using namespace mozilla;
 using namespace mozilla::net;
 
-static void
-ReleaseListenerAndContext(nsCOMPtr<nsIWebSocketListener>& aListener,
-                          nsCOMPtr<nsISupports>& aContext)
-{
-  nsCOMPtr<nsIThread> mainThread;
-  NS_GetMainThread(getter_AddRefs(mainThread));
-
-  if (aListener) {
-    NS_ProxyRelease(mainThread, aListener, false);
-  }
-
-  if (aContext) {
-    NS_ProxyRelease(mainThread, aContext, false);
-  }
-}
-
 namespace mozilla {
 namespace net {
 
 NS_IMPL_ISUPPORTS(WebSocketChannel,
                   nsIWebSocketChannel,
                   nsIHttpUpgradeListener,
                   nsIRequestObserver,
                   nsIStreamListener,
@@ -566,35 +550,31 @@ StaticMutex           nsWSAdmissionManag
 // CallOnMessageAvailable
 //-----------------------------------------------------------------------------
 
 class CallOnMessageAvailable MOZ_FINAL : public nsIRunnable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  CallOnMessageAvailable(WebSocketChannel* aChannel,
-                         nsACString& aData,
-                         int32_t aLen)
+  CallOnMessageAvailable(WebSocketChannel *aChannel,
+                         nsCString        &aData,
+                         int32_t           aLen)
     : mChannel(aChannel),
       mData(aData),
       mLen(aLen) {}
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(mChannel->IsOnTargetThread());
 
-    if (mChannel->mListener) {
-      if (mLen < 0) {
-        mChannel->mListener->OnMessageAvailable(mChannel->mContext, mData);
-      } else {
-        mChannel->mListener->OnBinaryMessageAvailable(mChannel->mContext, mData);
-      }
-    }
-
+    if (mLen < 0)
+      mChannel->mListener->OnMessageAvailable(mChannel->mContext, mData);
+    else
+      mChannel->mListener->OnBinaryMessageAvailable(mChannel->mContext, mData);
     return NS_OK;
   }
 
 private:
   ~CallOnMessageAvailable() {}
 
   nsRefPtr<WebSocketChannel>        mChannel;
   nsCString                         mData;
@@ -606,74 +586,64 @@ NS_IMPL_ISUPPORTS(CallOnMessageAvailable
 // CallOnStop
 //-----------------------------------------------------------------------------
 
 class CallOnStop MOZ_FINAL : public nsIRunnable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  // CallOnStop steals mListener and mContext from the aChannel in order to
-  // release them on the main thread when needed.
-  CallOnStop(WebSocketChannel* aChannel,
-             nsresult aReason)
+  CallOnStop(WebSocketChannel *aChannel,
+             nsresult          aReason)
     : mChannel(aChannel),
-      mReason(aReason)
-  {
-    mListener.swap(mChannel->mListener);
-    mContext.swap(mChannel->mContext);
-  }
+      mReason(aReason) {}
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(mChannel->IsOnTargetThread());
 
     nsWSAdmissionManager::OnStopSession(mChannel, mReason);
 
-    if (mListener) {
-      mListener->OnStop(mContext, mReason);
-      ReleaseListenerAndContext(mListener, mContext);
+    if (mChannel->mListener) {
+      mChannel->mListener->OnStop(mChannel->mContext, mReason);
+      mChannel->mListener = nullptr;
+      mChannel->mContext = nullptr;
     }
-
     return NS_OK;
   }
 
 private:
   ~CallOnStop() {}
 
   nsRefPtr<WebSocketChannel>        mChannel;
-  nsCOMPtr<nsIWebSocketListener>    mListener;
-  nsCOMPtr<nsISupports>             mContext;
   nsresult                          mReason;
 };
 NS_IMPL_ISUPPORTS(CallOnStop, nsIRunnable)
 
 //-----------------------------------------------------------------------------
 // CallOnServerClose
 //-----------------------------------------------------------------------------
 
 class CallOnServerClose MOZ_FINAL : public nsIRunnable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
 
-  CallOnServerClose(WebSocketChannel* aChannel,
-                    uint16_t aCode,
-                    nsACString& aReason)
+  CallOnServerClose(WebSocketChannel *aChannel,
+                    uint16_t          aCode,
+                    nsCString        &aReason)
     : mChannel(aChannel),
       mCode(aCode),
       mReason(aReason) {}
 
   NS_IMETHOD Run() MOZ_OVERRIDE
   {
     MOZ_ASSERT(mChannel->IsOnTargetThread());
 
-    if (mChannel->mListener) {
-      mChannel->mListener->OnServerClose(mChannel->mContext, mCode, mReason);
-    }
+    mChannel->mListener->OnServerClose(mChannel->mContext, mCode, mReason);
     return NS_OK;
   }
 
 private:
   ~CallOnServerClose() {}
 
   nsRefPtr<WebSocketChannel>        mChannel;
   uint16_t                          mCode;
@@ -683,29 +653,27 @@ NS_IMPL_ISUPPORTS(CallOnServerClose, nsI
 
 //-----------------------------------------------------------------------------
 // CallAcknowledge
 //-----------------------------------------------------------------------------
 
 class CallAcknowledge MOZ_FINAL : public nsCancelableRunnable
 {
 public:
-  CallAcknowledge(WebSocketChannel* aChannel,
-                  uint32_t aSize)
+  CallAcknowledge(WebSocketChannel *aChannel,
+                  uint32_t          aSize)
     : mChannel(aChannel),
       mSize(aSize) {}
 
   NS_IMETHOD Run()
   {
     MOZ_ASSERT(mChannel->IsOnTargetThread());
 
     LOG(("WebSocketChannel::CallAcknowledge: Size %u\n", mSize));
-    if (mChannel->mListener) {
-      mChannel->mListener->OnAcknowledge(mChannel->mContext, mSize);
-    }
+    mChannel->mListener->OnAcknowledge(mChannel->mContext, mSize);
     return NS_OK;
   }
 
 private:
   ~CallAcknowledge() {}
 
   nsRefPtr<WebSocketChannel>        mChannel;
   uint32_t                          mSize;
@@ -1201,17 +1169,27 @@ WebSocketChannel::~WebSocketChannel()
     NS_ProxyRelease(mainThread, forgettable, false);
   }
 
   if (mOriginalURI) {
     mOriginalURI.forget(&forgettable);
     NS_ProxyRelease(mainThread, forgettable, false);
   }
 
-  ReleaseListenerAndContext(mListener, mContext);
+  if (mListener) {
+    nsIWebSocketListener *forgettableListener;
+    mListener.forget(&forgettableListener);
+    NS_ProxyRelease(mainThread, forgettableListener, false);
+  }
+
+  if (mContext) {
+    nsISupports *forgettableContext;
+    mContext.forget(&forgettableContext);
+    NS_ProxyRelease(mainThread, forgettableContext, false);
+  }
 
   if (mLoadGroup) {
     nsILoadGroup *forgettableGroup;
     mLoadGroup.forget(&forgettableGroup);
     NS_ProxyRelease(mainThread, forgettableGroup, false);
   }
 
   if (mLoadInfo) {
@@ -2282,27 +2260,18 @@ WebSocketChannel::StopSession(nsresult r
     mCancelable->Cancel(NS_ERROR_UNEXPECTED);
     mCancelable = nullptr;
   }
 
   mPMCECompressor = nullptr;
 
   if (!mCalledOnStop) {
     mCalledOnStop = 1;
-
-    nsWSAdmissionManager::OnStopSession(this, reason);
-
-    nsRefPtr<CallOnStop> runnable = new CallOnStop(this, reason);
-
-    // CallOnStop steals mListener and mContext in order to release them on the
-    // main thread when needed.
-    MOZ_ASSERT(!mListener);
-    MOZ_ASSERT(!mContext);
-
-    mTargetThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
+    mTargetThread->Dispatch(new CallOnStop(this, reason),
+                            NS_DISPATCH_NORMAL);
   }
 }
 
 void
 WebSocketChannel::AbortSession(nsresult reason)
 {
   LOG(("WebSocketChannel::AbortSession() %p [reason %x] stopped = %d\n",
        this, reason, mStopped));