Bug 1150805 - WorkerPrivate should use nsTObserverArray for the WorkerFeatures. r=bent, a=abillings
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 07 Apr 2015 18:31:51 +0100
changeset 254874 84581cceafaf6785508efe8b8721985a0e4c59ea
parent 254873 77b62f4cb202922fdc9fa3c1509a853a7394f42e
child 254875 da142b0672349d9116d02aa00c74c1dfc8319b56
push id7890
push userryanvm@gmail.com
push dateTue, 07 Apr 2015 21:12:30 +0000
treeherdermozilla-aurora@da142b067234 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbent, abillings
bugs1150805
milestone39.0a2
Bug 1150805 - WorkerPrivate should use nsTObserverArray for the WorkerFeatures. r=bent, a=abillings
dom/base/WebSocket.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -120,18 +120,17 @@ public:
 
   nsresult ParseURL(const nsAString& aURL);
   nsresult InitializeConnection();
 
   // These methods when called can release the WebSocket object
   void FailConnection(uint16_t reasonCode,
                       const nsACString& aReasonString = EmptyCString());
   nsresult CloseConnection(uint16_t reasonCode,
-                           const nsACString& aReasonString = EmptyCString(),
-                           bool aCanceling = false);
+                           const nsACString& aReasonString = EmptyCString());
   nsresult Disconnect();
   void DisconnectInternal();
 
   nsresult ConsoleError();
   nsresult PrintErrorOnConsole(const char* aBundleURI,
                                const char16_t* aError,
                                const char16_t** aFormatStrings,
                                uint32_t aFormatStringsLen);
@@ -380,48 +379,16 @@ WebSocketImpl::PrintErrorOnConsole(const
   rv = console->LogMessage(errorObject);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 namespace {
 
-class CloseRunnable final : public WorkerMainThreadRunnable
-{
-public:
-  CloseRunnable(WebSocketImpl* aImpl, uint16_t aReasonCode,
-                const nsACString& aReasonString)
-    : WorkerMainThreadRunnable(aImpl->mWorkerPrivate)
-    , mImpl(aImpl)
-    , mReasonCode(aReasonCode)
-    , mReasonString(aReasonString)
-    , mRv(NS_ERROR_FAILURE)
-  { }
-
-  bool MainThreadRun() override
-  {
-    mRv = mImpl->mChannel->Close(mReasonCode, mReasonString);
-    return true;
-  }
-
-  nsresult ErrorCode() const
-  {
-    return mRv;
-  }
-
-private:
-  // A raw pointer because this runnable is sync.
-  WebSocketImpl* mImpl;
-
-  uint16_t mReasonCode;
-  const nsACString& mReasonString;
-  nsresult mRv;
-};
-
 class CancelWebSocketRunnable final : public nsRunnable
 {
 public:
   CancelWebSocketRunnable(nsIWebSocketChannel* aChannel, uint16_t aReasonCode,
                           const nsACString& aReasonString)
     : mChannel(aChannel)
     , mReasonCode(aReasonCode)
     , mReasonString(aReasonString)
@@ -464,21 +431,19 @@ public:
 private:
   WebSocketImpl* mImpl;
 };
 
 } // anonymous namespace
 
 nsresult
 WebSocketImpl::CloseConnection(uint16_t aReasonCode,
-                               const nsACString& aReasonString,
-                               bool aCanceling)
+                               const nsACString& aReasonString)
 {
   AssertIsOnTargetThread();
-  MOZ_ASSERT(!NS_IsMainThread() || !aCanceling);
 
   if (mDisconnectingOrDisconnected) {
     return NS_OK;
   }
 
   // If this method is called because the worker is going away, we will not
   // receive the OnStop() method and we have to disconnect the WebSocket and
   // release the WorkerFeature.
@@ -495,26 +460,19 @@ WebSocketImpl::CloseConnection(uint16_t 
     mWebSocket->SetReadyState(WebSocket::CLOSING);
 
     // The channel has to be closed on the main-thread.
 
     if (NS_IsMainThread()) {
       return mChannel->Close(aReasonCode, aReasonString);
     }
 
-    if (aCanceling) {
-      nsRefPtr<CancelWebSocketRunnable> runnable =
-        new CancelWebSocketRunnable(mChannel, aReasonCode, aReasonString);
-      return NS_DispatchToMainThread(runnable);
-    }
-
-    nsRefPtr<CloseRunnable> runnable =
-      new CloseRunnable(this, aReasonCode, aReasonString);
-    runnable->Dispatch(mWorkerPrivate->GetJSContext());
-    return runnable->ErrorCode();
+    nsRefPtr<CancelWebSocketRunnable> runnable =
+      new CancelWebSocketRunnable(mChannel, aReasonCode, aReasonString);
+    return NS_DispatchToMainThread(runnable);
   }
 
   // No channel, but not disconnected: canceled or failed early
   //
   MOZ_ASSERT(readyState == WebSocket::CONNECTING,
              "Should only get here for early websocket cancel/error");
 
   // Server won't be sending us a close code, so use what's passed in here.
@@ -2029,17 +1987,17 @@ public:
 
     if (aStatus >= Canceling) {
       {
         MutexAutoLock lock(mWebSocketImpl->mMutex);
         mWebSocketImpl->mWorkerShuttingDown = true;
       }
 
       mWebSocketImpl->CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY,
-                                      EmptyCString(), true);
+                                      EmptyCString());
     }
 
     return true;
   }
 
   bool Suspend(JSContext* aCx) override
   {
     {
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -5861,21 +5861,20 @@ WorkerPrivate::NotifyFeatures(JSContext*
   AssertIsOnWorkerThread();
 
   NS_ASSERTION(aStatus > Running, "Bad status!");
 
   if (aStatus >= Closing) {
     CancelAllTimeouts(aCx);
   }
 
-  nsAutoTArray<WorkerFeature*, 30> features;
-  features.AppendElements(mFeatures);
-
-  for (uint32_t index = 0; index < features.Length(); index++) {
-    if (!features[index]->Notify(aCx, aStatus)) {
+  nsTObserverArray<WorkerFeature*>::ForwardIterator iter(mFeatures);
+  while (iter.HasMore()) {
+    WorkerFeature* feature = iter.GetNext();
+    if (!feature->Notify(aCx, aStatus)) {
       NS_WARNING("Failed to notify feature!");
     }
   }
 
   nsAutoTArray<ParentType*, 10> children;
   children.AppendElements(mChildWorkers);
 
   for (uint32_t index = 0; index < children.Length(); index++) {
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -20,16 +20,17 @@
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsRefPtrHashtable.h"
 #include "nsString.h"
 #include "nsTArray.h"
 #include "nsThreadUtils.h"
+#include "nsTObserverArray.h"
 #include "mozilla/dom/StructuredCloneTags.h"
 
 #include "Queue.h"
 #include "WorkerFeature.h"
 
 class JSAutoStructuredCloneBuffer;
 class nsIChannel;
 class nsIDocument;
@@ -808,17 +809,17 @@ class WorkerPrivate : public WorkerPriva
   nsTArray<nsCOMPtr<nsIRunnable>> mUndispatchedRunnablesForSyncLoop;
   nsRefPtr<WorkerThread> mThread;
   PRThread* mPRThread;
 
   // Things touched on worker thread only.
   nsRefPtr<WorkerGlobalScope> mScope;
   nsRefPtr<WorkerDebuggerGlobalScope> mDebuggerScope;
   nsTArray<ParentType*> mChildWorkers;
-  nsTArray<WorkerFeature*> mFeatures;
+  nsTObserverArray<WorkerFeature*> mFeatures;
   nsTArray<nsAutoPtr<TimeoutInfo>> mTimeouts;
   uint32_t mDebuggerEventLoopLevel;
 
   struct SyncLoopInfo
   {
     explicit SyncLoopInfo(EventTarget* aEventTarget);
 
     nsRefPtr<EventTarget> mEventTarget;