Bug 1530223: Use ThreadBound for RemoteWorkerChild members accessed on launcher thread r=perry,asuth
authorYaron Tausky <ytausky@mozilla.com>
Wed, 06 Mar 2019 19:00:10 +0000
changeset 520564 ed0f9b04cb90ae9959ed5d37bec8454c676ff48e
parent 520563 c66813164419e99c5e8d0343a0386a0251550455
child 520565 ac5ecad3f2d06ef972425ad47e4d402870746d49
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersperry, asuth
bugs1530223
milestone67.0a1
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
Bug 1530223: Use ThreadBound for RemoteWorkerChild members accessed on launcher thread r=perry,asuth This adds runtime checks that verify thread safety. Differential Revision: https://phabricator.services.mozilla.com/D22338
dom/workers/remoteworkers/RemoteWorkerChild.cpp
dom/workers/remoteworkers/RemoteWorkerChild.h
--- a/dom/workers/remoteworkers/RemoteWorkerChild.cpp
+++ b/dom/workers/remoteworkers/RemoteWorkerChild.cpp
@@ -196,18 +196,19 @@ RemoteWorkerChild::~RemoteWorkerChild() 
   nsCOMPtr<nsIEventTarget> target =
       SystemGroup::EventTargetFor(TaskCategory::Other);
 
   NS_ProxyRelease("RemoteWorkerChild::mWorkerPrivate", target,
                   mWorkerPrivate.forget());
 }
 
 void RemoteWorkerChild::ActorDestroy(ActorDestroyReason aWhy) {
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
   mIPCActive = false;
-  mPendingOps.Clear();
+  data->mPendingOps.Clear();
 }
 
 void RemoteWorkerChild::ExecWorker(const RemoteWorkerData& aData) {
   MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
   MOZ_ASSERT(mIPCActive);
 
   RefPtr<RemoteWorkerChild> self = this;
   nsCOMPtr<nsIRunnable> r =
@@ -362,20 +363,20 @@ void RemoteWorkerChild::ShutdownOnWorker
   nsCOMPtr<nsIRunnable> r =
       NS_NewRunnableFunction("RemoteWorkerChild::ShutdownOnWorker",
                              [self]() { self->WorkerTerminated(); });
 
   RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
 void RemoteWorkerChild::WorkerTerminated() {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
 
   mWorkerState = eTerminated;
-  mPendingOps.Clear();
+  data->mPendingOps.Clear();
 
   if (!mIPCActive) {
     return;
   }
 
   Unused << SendClose();
   mIPCActive = false;
 }
@@ -464,23 +465,25 @@ void RemoteWorkerChild::FlushReportsOnMa
     aReporter->FlushReportsToConsole(0);
     return;
   }
 
   aReporter->ClearConsoleReports();
 }
 
 IPCResult RemoteWorkerChild::RecvExecOp(const RemoteWorkerOp& aOp) {
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
+
   if (!mIPCActive) {
     return IPC_OK();
   }
 
   // The worker is not ready yet.
   if (mWorkerState == ePending) {
-    mPendingOps.AppendElement(aOp);
+    data->mPendingOps.AppendElement(aOp);
     return IPC_OK();
   }
 
   if (mWorkerState == eTerminated || mWorkerState == ePendingTerminated) {
     // No op.
     return IPC_OK();
   }
 
@@ -584,17 +587,17 @@ void RemoteWorkerChild::CreationSucceede
   nsCOMPtr<nsIRunnable> r =
       NS_NewRunnableFunction("RemoteWorkerChild::CreationSucceededOnAnyThread",
                              [self]() { self->CreationSucceeded(); });
 
   RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
 void RemoteWorkerChild::CreationSucceeded() {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
 
   // The worker is created but we need to terminate it already.
   if (mWorkerState == ePendingTerminated) {
     RefPtr<RemoteWorkerChild> self = this;
     nsCOMPtr<nsIRunnable> r =
         NS_NewRunnableFunction("RemoteWorkerChild::CreationSucceeded",
                                [self]() { self->CloseWorkerOnMainThread(); });
 
@@ -605,39 +608,39 @@ void RemoteWorkerChild::CreationSucceede
   }
 
   mWorkerState = eRunning;
 
   if (!mIPCActive) {
     return;
   }
 
-  for (const RemoteWorkerOp& op : mPendingOps) {
+  for (const RemoteWorkerOp& op : data->mPendingOps) {
     RecvExecOp(op);
   }
 
-  mPendingOps.Clear();
+  data->mPendingOps.Clear();
 
   Unused << SendCreated(true);
 }
 
 void RemoteWorkerChild::CreationFailedOnAnyThread() {
   RefPtr<RemoteWorkerChild> self = this;
   nsCOMPtr<nsIRunnable> r =
       NS_NewRunnableFunction("RemoteWorkerChild::CreationFailedOnAnyThread",
                              [self]() { self->CreationFailed(); });
 
   RemoteWorkerService::Thread()->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
 }
 
 void RemoteWorkerChild::CreationFailed() {
-  MOZ_ASSERT(RemoteWorkerService::Thread()->IsOnCurrentThread());
+  MOZ_ACCESS_THREAD_BOUND(mLauncherData, data);
 
   mWorkerState = eTerminated;
-  mPendingOps.Clear();
+  data->mPendingOps.Clear();
 
   if (!mIPCActive) {
     return;
   }
 
   Unused << SendCreated(false);
 }
 
--- a/dom/workers/remoteworkers/RemoteWorkerChild.h
+++ b/dom/workers/remoteworkers/RemoteWorkerChild.h
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_dom_RemoteWorkerChild_h
 #define mozilla_dom_RemoteWorkerChild_h
 
 #include "mozilla/dom/PRemoteWorkerChild.h"
+#include "mozilla/ThreadBound.h"
 #include "mozilla/UniquePtr.h"
 #include "nsISupportsImpl.h"
 
 class nsIConsoleReportCollector;
 
 namespace mozilla {
 namespace dom {
 
@@ -94,15 +95,19 @@ class RemoteWorkerChild final : public P
     // Worker terminated.
     eTerminated,
   };
 
   // Touched only on the owning thread (Worker Launcher).
   WorkerState mWorkerState;
 
   // Touched only on the owning thread (Worker Launcher).
-  nsTArray<RemoteWorkerOp> mPendingOps;
+  struct LauncherBoundData {
+    nsTArray<RemoteWorkerOp> mPendingOps;
+  };
+
+  ThreadBound<LauncherBoundData> mLauncherData;
 };
 
 }  // namespace dom
 }  // namespace mozilla
 
 #endif  // mozilla_dom_RemoteWorkerChild_h