Backed out 7 changesets (bug 1450644, bug 1454633) for for failing browser_storage_permission.js on a CLOSED TREE
authorTiberius Oros <toros@mozilla.com>
Wed, 18 Apr 2018 01:10:26 +0300
changeset 467721 73615fe67ab6424c9334f95c39a74fc224977993
parent 467720 10424496394b06514993cd78c6521ef100795ebf
child 467722 56c287941f2a60a7ea18baf45ffc526c4cd137e2
push id9165
push userasasaki@mozilla.com
push dateThu, 26 Apr 2018 21:04:54 +0000
treeherdermozilla-beta@064c3804de2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1450644, 1454633
milestone61.0a1
backs outf4989e0da2216f6cf3fbe3d3a616d31447f068ec
08239799d43e6ddb85c9d149622151702ddac6f6
cbe3ad4833b670227c4b229dbbe29954d4b9fc25
0d2088370d0c8bad625758d8c1cc49761293501b
246fb3ee14cd82024354f82cac6c97f48139c3d1
629e499c0f754bc3cce971bd1a90310ce04114ab
ed93e3547096537e7cd76cdae83e83573c30dcb3
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 7 changesets (bug 1450644, bug 1454633) for for failing browser_storage_permission.js on a CLOSED TREE Backed out changeset f4989e0da221 (bug 1454633) Backed out changeset 08239799d43e (bug 1450644) Backed out changeset cbe3ad4833b6 (bug 1450644) Backed out changeset 0d2088370d0c (bug 1450644) Backed out changeset 246fb3ee14cd (bug 1450644) Backed out changeset 629e499c0f75 (bug 1450644) Backed out changeset ed93e3547096 (bug 1450644)
dom/base/DOMPrefs.cpp
dom/base/DOMPrefs.h
dom/base/DOMPrefsInternal.h
dom/broadcastchannel/BroadcastChannel.cpp
dom/broadcastchannel/BroadcastChannel.h
dom/clients/api/Client.cpp
dom/clients/api/ClientDOMUtil.h
dom/clients/manager/ClientManager.cpp
dom/messagechannel/MessagePort.cpp
dom/websocket/WebSocket.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerPrivate.h
dom/workers/WorkerRef.cpp
dom/workers/test/WorkerDebugger_sharedWorker.js
dom/workers/test/test_WorkerDebugger.xul
modules/libpref/Preferences.cpp
testing/web-platform/tests/webmessaging/broadcastchannel/workers.html
--- a/dom/base/DOMPrefs.cpp
+++ b/dom/base/DOMPrefs.cpp
@@ -18,23 +18,21 @@ DOMPrefs::Initialize()
 
   // Let's cache all the values on the main-thread.
 #if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
   DOMPrefs::DumpEnabled();
 #endif
 
 #define DOM_PREF(name, pref) DOMPrefs::name();
 #define DOM_WEBIDL_PREF(name)
-#define DOM_UINT32_PREF(name, pref, defaultValue) DOMPrefs::name();
 
 #include "DOMPrefsInternal.h"
 
 #undef DOM_PREF
 #undef DOM_WEBIDL_PREF
-#undef DOM_UINT32_PREF
 }
 
 #define DOM_PREF(name, pref)                                         \
   /* static */ bool                                                  \
   DOMPrefs::name()                                                   \
   {                                                                  \
     static bool initialized = false;                                 \
     static Atomic<bool> cachedValue;                                 \
@@ -47,39 +45,25 @@ DOMPrefs::Initialize()
 
 #define DOM_WEBIDL_PREF(name)                    \
   /* static */ bool                              \
   DOMPrefs::name(JSContext* aCx, JSObject* aObj) \
   {                                              \
     return DOMPrefs::name();                     \
   }
 
-#define DOM_UINT32_PREF(name, pref, defaultValue)                             \
-  /* static */ uint32_t                                                       \
-  DOMPrefs::name()                                                            \
-  {                                                                           \
-      static bool initialized = false;                                        \
-      static Atomic<uint32_t> cachedValue;                                    \
-      if (!initialized) {                                                     \
-        initialized = true;                                                   \
-        Preferences::AddAtomicUintVarCache(&cachedValue, pref, defaultValue); \
-    }                                                                         \
-    return cachedValue;                                                       \
-  }
-
 #if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
 DOM_PREF(DumpEnabled, "browser.dom.window.dump.enabled")
 #else
 /* static */ bool
 DOMPrefs::DumpEnabled()
 {
   return true;
 }
 #endif
 
 #include "DOMPrefsInternal.h"
 
 #undef DOM_PREF
 #undef DOM_WEBIDL_PREF
-#undef DOM_UINT32_PREF
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/base/DOMPrefs.h
+++ b/dom/base/DOMPrefs.h
@@ -16,21 +16,19 @@ public:
   // This must be called on the main-thread.
   static void Initialize();
 
   // Returns true if the browser.dom.window.dump.enabled pref is set.
   static bool DumpEnabled();
 
 #define DOM_PREF(name, pref) static bool name();
 #define DOM_WEBIDL_PREF(name) static bool name(JSContext* aCx, JSObject* aObj);
-#define DOM_UINT32_PREF(name, pref, defaultValue) static uint32_t name();
 
 #include "DOMPrefsInternal.h"
 
 #undef DOM_PREF
 #undef DOM_WEBIDL_PREF
-#undef DOM_UINT32_PREF
 };
 
 } // dom namespace
 } // mozilla namespace
 
 #endif // mozilla_dom_DOMPrefs_h
--- a/dom/base/DOMPrefsInternal.h
+++ b/dom/base/DOMPrefsInternal.h
@@ -51,12 +51,8 @@ DOM_WEBIDL_PREF(StorageManagerEnabled)
 DOM_WEBIDL_PREF(PromiseRejectionEventsEnabled)
 DOM_WEBIDL_PREF(PushEnabled)
 DOM_WEBIDL_PREF(StreamsEnabled)
 DOM_WEBIDL_PREF(OffscreenCanvasEnabled)
 DOM_WEBIDL_PREF(WebkitBlinkDirectoryPickerEnabled)
 DOM_WEBIDL_PREF(NetworkInformationEnabled)
 DOM_WEBIDL_PREF(FetchObserverEnabled)
 DOM_WEBIDL_PREF(PerformanceObserverEnabled)
-
-DOM_UINT32_PREF(WorkerCancelingTimeoutMillis,
-                "dom.worker.canceling.timeoutMilliseconds",
-                30000 /* 30 seconds */)
--- a/dom/broadcastchannel/BroadcastChannel.cpp
+++ b/dom/broadcastchannel/BroadcastChannel.cpp
@@ -306,25 +306,25 @@ BroadcastChannel::Constructor(const Glob
     MOZ_ASSERT(workerPrivate);
 
     RefPtr<StrongWorkerRef> workerRef =
       StrongWorkerRef::Create(workerPrivate, "BroadcastChannel",
                               [bc] () { bc->Shutdown(); });
     // We are already shutting down the worker. Let's return a non-active
     // object.
     if (NS_WARN_IF(!workerRef)) {
-      aRv.Throw(NS_ERROR_FAILURE);
-      return nullptr;
+      bc->mState = StateClosed;
+      return bc.forget();
     }
 
     RefPtr<ThreadSafeWorkerRef> tsr = new ThreadSafeWorkerRef(workerRef);
 
     RefPtr<InitializeRunnable> runnable =
       new InitializeRunnable(tsr, origin, principalInfo, aRv);
-    runnable->Dispatch(Canceling, aRv);
+    runnable->Dispatch(Closing, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
 
     bc->mWorkerRef = Move(workerRef);
   }
 
   // Register this component to PBackground.
--- a/dom/broadcastchannel/BroadcastChannel.h
+++ b/dom/broadcastchannel/BroadcastChannel.h
@@ -63,16 +63,21 @@ public:
   void Shutdown();
 
 private:
   BroadcastChannel(nsPIDOMWindowInner* aWindow,
                    const nsAString& aChannel);
 
   ~BroadcastChannel();
 
+  void PostMessageData(BroadcastChannelMessage* aData);
+
+  void PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+                           ErrorResult& aRv);
+
   void RemoveDocFromBFCache();
 
   void DisconnectFromOwner() override;
 
   RefPtr<BroadcastChannelChild> mActor;
 
   RefPtr<WorkerRef> mWorkerRef;
 
--- a/dom/clients/api/Client.cpp
+++ b/dom/clients/api/Client.cpp
@@ -171,17 +171,17 @@ Client::Focus(ErrorResult& aRv)
     outerPromise->MaybeReject(NS_ERROR_DOM_INVALID_ACCESS_ERR);
     return outerPromise.forget();
   }
 
   // Hold the worker thread alive while we perform the async operation
   // and also avoid invoking callbacks if the worker starts shutting
   // down.
   RefPtr<WorkerHolderToken> token =
-    WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(), Terminating);
+    WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(), Closing);
 
   EnsureHandle();
   RefPtr<ClientStatePromise> innerPromise = mHandle->Focus();
   RefPtr<Client> self = this;
 
   innerPromise->Then(mGlobal->EventTargetFor(TaskCategory::Other), __func__,
     [self, token, outerPromise] (const ClientState& aResult) {
       if (token->IsShuttingDown()) {
--- a/dom/clients/api/ClientDOMUtil.h
+++ b/dom/clients/api/ClientDOMUtil.h
@@ -22,17 +22,17 @@ namespace dom {
 template<typename Func, typename Arg, typename Resolve, typename Reject>
 void
 StartClientManagerOp(Func aFunc, const Arg& aArg, nsISerialEventTarget* aTarget,
                      Resolve aResolve, Reject aReject)
 {
   RefPtr<WorkerHolderToken> token;
   if (!NS_IsMainThread()) {
     token = WorkerHolderToken::Create(GetCurrentThreadWorkerPrivate(),
-                                      WorkerStatus::Terminating);
+                                      WorkerStatus::Closing);
   }
 
   RefPtr<ClientOpPromise> promise = aFunc(aArg, aTarget);
   promise->Then(aTarget, __func__,
     [aResolve, token](const ClientOpResult& aResult) {
       if (token && token->IsShuttingDown()) {
         return;
       }
--- a/dom/clients/manager/ClientManager.cpp
+++ b/dom/clients/manager/ClientManager.cpp
@@ -41,17 +41,17 @@ ClientManager::ClientManager()
   }
 
   RefPtr<WorkerHolderToken> workerHolderToken;
   if (!NS_IsMainThread()) {
     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     MOZ_DIAGNOSTIC_ASSERT(workerPrivate);
 
     workerHolderToken =
-      WorkerHolderToken::Create(workerPrivate, Terminating,
+      WorkerHolderToken::Create(workerPrivate, Closing,
                                 WorkerHolderToken::AllowIdleShutdownStart);
     if (NS_WARN_IF(!workerHolderToken)) {
       Shutdown();
       return;
     }
   }
 
   ClientManagerChild* actor = new ClientManagerChild(workerHolderToken);
--- a/dom/messagechannel/MessagePort.cpp
+++ b/dom/messagechannel/MessagePort.cpp
@@ -292,18 +292,18 @@ MessagePort::Initialize(const nsID& aUUI
     MOZ_ASSERT(workerPrivate);
 
     // When the callback is executed, we cannot process messages anymore because
     // we cannot dispatch new runnables. Let's force a Close().
     RefPtr<StrongWorkerRef> strongWorkerRef =
       StrongWorkerRef::Create(workerPrivate, "MessagePort",
                               [self]() { self->CloseForced(); });
     if (NS_WARN_IF(!strongWorkerRef)) {
-      // The worker is shutting down.
-      aRv.Throw(NS_ERROR_FAILURE);
+      // The worker is shutting down. Let's return an already closed port.
+      mState = eStateDisentangledForClose;
       return;
     }
 
     MOZ_ASSERT(!mWorkerRef);
     mWorkerRef = Move(strongWorkerRef);
   } else if (GetOwner()) {
     MOZ_ASSERT(NS_IsMainThread());
     mInnerID = GetOwner()->WindowID();
--- a/dom/websocket/WebSocket.cpp
+++ b/dom/websocket/WebSocket.cpp
@@ -567,17 +567,17 @@ WebSocketImpl::FailConnection(uint16_t a
 }
 
 namespace {
 
 class DisconnectInternalRunnable final : public WorkerMainThreadRunnable
 {
 public:
   explicit DisconnectInternalRunnable(WebSocketImpl* aImpl)
-    : WorkerMainThreadRunnable(GetCurrentThreadWorkerPrivate(),
+    : WorkerMainThreadRunnable(aImpl->mWorkerRef->Private(),
                                NS_LITERAL_CSTRING("WebSocket :: disconnect"))
     , mImpl(aImpl)
   { }
 
   bool MainThreadRun() override
   {
     mImpl->DisconnectInternal();
     return true;
@@ -615,17 +615,17 @@ WebSocketImpl::Disconnect()
   if (NS_IsMainThread()) {
     DisconnectInternal();
 
     // If we haven't called WebSocket::DisconnectFromOwner yet, update
     // web socket count here.
     if (mWebSocket->GetOwner()) {
       mWebSocket->GetOwner()->UpdateWebSocketCount(-1);
     }
-  } else {
+  } else if (mWorkerRef) {
     RefPtr<DisconnectInternalRunnable> runnable =
       new DisconnectInternalRunnable(this);
     ErrorResult rv;
     runnable->Dispatch(Killing, rv);
     // XXXbz this seems totally broken.  We should be propagating this out, but
     // where to, exactly?
     rv.SuppressException();
   }
@@ -1398,24 +1398,28 @@ WebSocket::ConstructorCommon(const Globa
     }
 
     aRv = runnable->ErrorCode();
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
     if (NS_WARN_IF(!webSocketImpl->RegisterWorkerRef(workerPrivate))) {
-      // The worker is shutting down.
-      aRv.Throw(NS_ERROR_FAILURE);
-      return nullptr;
+      // The worker is shutting down. We cannot proceed but we return a
+      // 'connecting' object.
+      webSocketImpl->mWorkerShuttingDown = true;
+      webSocketImpl->Disconnect();
+      return webSocket.forget();
     }
 
     RefPtr<ConnectRunnable> connectRunnable =
       new ConnectRunnable(workerPrivate, webSocketImpl);
-    connectRunnable->Dispatch(Canceling, aRv);
+    // We can use Closing because we have a WorkerRef and that is enough to be
+    // sure that the worker is up and running.
+    connectRunnable->Dispatch(Closing, aRv);
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
     connectionFailed = connectRunnable->ConnectionFailed();
   }
 
   // It can be that we have been already disconnected because the WebSocket is
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3,17 +3,16 @@
 /* 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/. */
 
 #include "WorkerPrivate.h"
 
 #include "js/MemoryMetrics.h"
 #include "MessageEventRunnable.h"
-#include "mozilla/ScopeExit.h"
 #include "mozilla/dom/ClientManager.h"
 #include "mozilla/dom/ClientSource.h"
 #include "mozilla/dom/ClientState.h"
 #include "mozilla/dom/Console.h"
 #include "mozilla/dom/DOMTypes.h"
 #include "mozilla/dom/ErrorEvent.h"
 #include "mozilla/dom/ErrorEventBinding.h"
 #include "mozilla/dom/Event.h"
@@ -972,103 +971,16 @@ class SimpleWorkerHolder final : public 
 public:
   SimpleWorkerHolder()
     : WorkerHolder("SimpleWorkerHolder")
   {}
 
   virtual bool Notify(WorkerStatus aStatus) override { return true; }
 };
 
-// A runnable to cancel the worker from the parent thread when self.close() is
-// called. This runnable is executed on the parent process in order to cancel
-// the current runnable. It uses a normal WorkerRunnable in order to be sure
-// that all the pending WorkerRunnables are executed before this.
-class CancelingOnParentRunnable final : public WorkerRunnable
-{
-public:
-  explicit CancelingOnParentRunnable(WorkerPrivate* aWorkerPrivate)
-    : WorkerRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
-  {}
-
-  bool
-  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
-  {
-    aWorkerPrivate->Cancel();
-    return true;
-  }
-};
-
-// A runnable to cancel the worker from the parent process.
-class CancelingWithTimeoutOnParentRunnable final : public WorkerControlRunnable
-{
-public:
-  explicit CancelingWithTimeoutOnParentRunnable(WorkerPrivate* aWorkerPrivate)
-    : WorkerControlRunnable(aWorkerPrivate, ParentThreadUnchangedBusyCount)
-  {}
-
-  bool
-  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
-  {
-    aWorkerPrivate->AssertIsOnParentThread();
-    aWorkerPrivate->StartCancelingTimer();
-    return true;
-  }
-};
-
-class CancelingTimerCallback final : public nsITimerCallback
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  explicit CancelingTimerCallback(WorkerPrivate* aWorkerPrivate)
-    : mWorkerPrivate(aWorkerPrivate)
-  {}
-
-  NS_IMETHOD
-  Notify(nsITimer* aTimer) override
-  {
-    mWorkerPrivate->AssertIsOnParentThread();
-    mWorkerPrivate->Cancel();
-    return NS_OK;
-  }
-
-private:
-  ~CancelingTimerCallback() = default;
-
-  // Raw pointer here is OK because the timer is canceled during the shutdown
-  // steps.
-  WorkerPrivate* mWorkerPrivate;
-};
-
-NS_IMPL_ISUPPORTS(CancelingTimerCallback, nsITimerCallback)
-
-// This runnable starts the canceling of a worker after a self.close().
-class CancelingRunnable final : public Runnable
-{
-public:
-  CancelingRunnable()
-    : Runnable("CancelingRunnable")
-  {}
-
-  NS_IMETHOD
-  Run() override
-  {
-    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
-    MOZ_ASSERT(workerPrivate);
-    workerPrivate->AssertIsOnWorkerThread();
-
-    // Now we can cancel the this worker from the parent process.
-    RefPtr<CancelingOnParentRunnable> r =
-      new CancelingOnParentRunnable(workerPrivate);
-    r->Dispatch();
-
-    return NS_OK;
-  }
-};
-
 } /* anonymous namespace */
 
 class WorkerPrivate::EventTarget final : public nsISerialEventTarget
 {
   // This mutex protects mWorkerPrivate and must be acquired *before* the
   // WorkerPrivate's mutex whenever they must both be held.
   mozilla::Mutex mMutex;
   WorkerPrivate* mWorkerPrivate;
@@ -1820,22 +1732,16 @@ WorkerPrivate::NotifyPrivate(WorkerStatu
   }
 
   NS_ASSERTION(aStatus != Terminating || mQueuedRunnables.IsEmpty(),
                "Shouldn't have anything queued!");
 
   // Anything queued will be discarded.
   mQueuedRunnables.Clear();
 
-  // No Canceling timeout is needed.
-  if (mCancelingTimer) {
-    mCancelingTimer->Cancel();
-    mCancelingTimer = nullptr;
-  }
-
   RefPtr<NotifyRunnable> runnable = new NotifyRunnable(this, aStatus);
   return runnable->Dispatch();
 }
 
 bool
 WorkerPrivate::Freeze(nsPIDOMWindowInner* aWindow)
 {
   AssertIsOnParentThread();
@@ -3698,23 +3604,16 @@ WorkerPrivate::InterruptCallback(JSConte
   }
 
   // Make sure the periodic timer gets turned back on here.
   SetGCTimerMode(PeriodicTimer);
 
   return true;
 }
 
-void
-WorkerPrivate::CloseInternal()
-{
-  AssertIsOnWorkerThread();
-  NotifyInternal(Closing);
-}
-
 bool
 WorkerPrivate::IsOnCurrentThread()
 {
   // May be called on any thread!
 
   MOZ_ASSERT(mPRThread);
   return PR_GetCurrentThread() == mPRThread;
 }
@@ -4574,34 +4473,18 @@ WorkerPrivate::NotifyInternal(WorkerStat
   }
 
   // If the worker script never ran, or failed to compile, we don't need to do
   // anything else.
   if (!GlobalScope()) {
     return true;
   }
 
-  // Don't abort the script now, but we dispatch a runnable to do it when the
-  // current JS frame is executed.
+  // Don't abort the script.
   if (aStatus == Closing) {
-    if (mSyncLoopStack.IsEmpty()) {
-      // Here we use a normal runnable to know when the current JS chunk of code
-      // is finished. We cannot use a WorkerRunnable because they are not
-      // accepted any more by the worker, and we do not want to use a
-      // WorkerControlRunnable because they are immediately executed.
-      RefPtr<CancelingRunnable> r = new CancelingRunnable();
-      mThread->nsThread::Dispatch(r.forget(), NS_DISPATCH_NORMAL);
-
-      // At the same time, we want to be sure that we interrupt infinite loops.
-      // The following runnable starts a timer that cancel the worker, from the
-      // parent thread, after CANCELING_TIMEOUT millseconds.
-      RefPtr<CancelingWithTimeoutOnParentRunnable> rr =
-        new CancelingWithTimeoutOnParentRunnable(this);
-      rr->Dispatch();
-    }
     return true;
   }
 
   MOZ_ASSERT(aStatus == Terminating ||
              aStatus == Canceling ||
              aStatus == Killing);
 
   // Always abort the script.
@@ -4959,58 +4842,16 @@ WorkerPrivate::RescheduleTimeoutTimer(JS
     JS_ReportErrorASCII(aCx, "Failed to start timer!");
     return false;
   }
 
   return true;
 }
 
 void
-WorkerPrivate::StartCancelingTimer()
-{
-  AssertIsOnParentThread();
-
-  auto errorCleanup = MakeScopeExit([&] {
-    mCancelingTimer = nullptr;
-  });
-
-  MOZ_ASSERT(!mCancelingTimer);
-
-  if (WorkerPrivate* parent = GetParent()) {
-    mCancelingTimer = NS_NewTimer(parent->ControlEventTarget());
-  } else {
-    mCancelingTimer = NS_NewTimer();
-  }
-
-  if (NS_WARN_IF(!mCancelingTimer)) {
-    return;
-  }
-
-  // This is not needed if we are already in an advanced shutdown state.
-  {
-    MutexAutoLock lock(mMutex);
-    if (ParentStatus() >= Terminating) {
-      return;
-    }
-  }
-
-  uint32_t cancelingTimeoutMillis = DOMPrefs::WorkerCancelingTimeoutMillis();
-
-  RefPtr<CancelingTimerCallback> callback = new CancelingTimerCallback(this);
-  nsresult rv = mCancelingTimer->InitWithCallback(callback,
-                                                  cancelingTimeoutMillis,
-                                                  nsITimer::TYPE_ONE_SHOT);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return;
-  }
-
-  errorCleanup.release();
-}
-
-void
 WorkerPrivate::UpdateContextOptionsInternal(
                                     JSContext* aCx,
                                     const JS::ContextOptions& aContextOptions)
 {
   AssertIsOnWorkerThread();
 
   JS::ContextOptionsRef(aCx) = aContextOptions;
 
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -258,18 +258,22 @@ public:
   DoRunLoop(JSContext* aCx);
 
   bool
   InterruptCallback(JSContext* aCx);
 
   bool
   IsOnCurrentThread();
 
-  void
-  CloseInternal();
+  bool
+  CloseInternal()
+  {
+    AssertIsOnWorkerThread();
+    return NotifyInternal(Closing);
+  }
 
   bool
   FreezeInternal();
 
   bool
   ThawInternal();
 
   void
@@ -1204,19 +1208,16 @@ public:
   { }
 #endif
 
 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
   bool
   PrincipalIsValid() const;
 #endif
 
-  void
-  StartCancelingTimer();
-
 private:
   WorkerPrivate(WorkerPrivate* aParent,
                 const nsAString& aScriptURL, bool aIsChromeWorker,
                 WorkerType aWorkerType, const nsAString& aWorkerName,
                 const nsACString& aServiceWorkerScope,
                 WorkerLoadInfo& aLoadInfo);
 
   ~WorkerPrivate();
@@ -1419,18 +1420,16 @@ private:
   // This is only modified on the worker thread, but in DEBUG builds
   // AssertValidSyncLoop function iterates it on other threads. Therefore
   // modifications are done with mMutex held *only* in DEBUG builds.
   nsTArray<nsAutoPtr<SyncLoopInfo>> mSyncLoopStack;
 
   nsCOMPtr<nsITimer> mTimer;
   nsCOMPtr<nsITimerCallback> mTimerRunnable;
 
-  nsCOMPtr<nsITimer> mCancelingTimer;
-
   nsCOMPtr<nsITimer> mGCTimer;
 
   RefPtr<MemoryReporter> mMemoryReporter;
 
   // fired on the main thread if the worker script fails to load
   nsCOMPtr<nsIRunnable> mLoadFailedRunnable;
 
   RefPtr<PerformanceStorage> mPerformanceStorage;
--- a/dom/workers/WorkerRef.cpp
+++ b/dom/workers/WorkerRef.cpp
@@ -65,20 +65,16 @@ public:
     , mWorkerRef(aWorkerRef)
   {}
 
   bool
   Notify(WorkerStatus aStatus) override
   {
     MOZ_ASSERT(mWorkerRef);
 
-    if (aStatus < Canceling) {
-      return true;
-    }
-
     // Let's keep this object alive for the whole Notify() execution.
     RefPtr<WorkerRef> workerRef;
     workerRef = mWorkerRef;
 
     workerRef->Notify();
     return true;
   }
 
@@ -127,17 +123,17 @@ WeakWorkerRef::Create(WorkerPrivate* aWo
   MOZ_ASSERT(aWorkerPrivate);
   aWorkerPrivate->AssertIsOnWorkerThread();
 
   RefPtr<WeakWorkerRef> ref = new WeakWorkerRef(aWorkerPrivate);
 
   // This holder doesn't keep the worker alive.
   UniquePtr<Holder> holder(new Holder("WeakWorkerRef::Holder", ref,
                                       WorkerHolder::AllowIdleShutdownStart));
-  if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
+  if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Closing))) {
     return nullptr;
   }
 
   ref->mHolder = Move(holder);
   ref->mCallback = aCallback;
 
   return ref.forget();
 }
@@ -181,17 +177,17 @@ StrongWorkerRef::Create(WorkerPrivate* a
   MOZ_ASSERT(aWorkerPrivate);
   MOZ_ASSERT(aName);
 
   RefPtr<StrongWorkerRef> ref = new StrongWorkerRef(aWorkerPrivate);
 
   // The worker is kept alive by this holder.
   UniquePtr<Holder> holder(new Holder(aName, ref,
                                       WorkerHolder::PreventIdleShutdownStart));
-  if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Canceling))) {
+  if (NS_WARN_IF(!holder->HoldWorker(aWorkerPrivate, Closing))) {
     return nullptr;
   }
 
   ref->mHolder = Move(holder);
   ref->mCallback = aCallback;
 
   return ref.forget();
 }
--- a/dom/workers/test/WorkerDebugger_sharedWorker.js
+++ b/dom/workers/test/WorkerDebugger_sharedWorker.js
@@ -1,17 +1,11 @@
 "use strict";
 
 self.onconnect = function (event) {
   event.ports[0].onmessage = function (event) {
     switch (event.data) {
     case "close":
       close();
       break;
-
-    case "close_loop":
-      close();
-      // Let's loop forever.
-      while(1) {}
-      break;
     }
   };
 };
--- a/dom/workers/test/test_WorkerDebugger.xul
+++ b/dom/workers/test/test_WorkerDebugger.xul
@@ -18,17 +18,16 @@
 
     const WORKER_URL = "WorkerDebugger_worker.js";
     const CHILD_WORKER_URL = "WorkerDebugger_childWorker.js";
     const SHARED_WORKER_URL = "WorkerDebugger_sharedWorker.js";
 
     function test() {
       (async function() {
         SimpleTest.waitForExplicitFinish();
-        SimpleTest.requestLongerTimeout(5);
 
         info("Create a top-level chrome worker that creates a non-top-level " +
              "content worker and wait for their debuggers to be registered.");
         let promise = waitForMultiple([
           waitForRegister(WORKER_URL),
           waitForRegister(CHILD_WORKER_URL)
         ]);
         worker = new ChromeWorker(WORKER_URL);
@@ -52,28 +51,28 @@
         is(childDbg.parent, dbg,
            "Non-top-level worker debugger should have parent.");
         is(childDbg.type, Ci.nsIWorkerDebugger.TYPE_DEDICATED,
            "Content worker debugger should be dedicated.");
         is(childDbg.window, null,
            "Non-top-level worker debugger should not have window.");
 
         info("Terminate the top-level chrome worker and the non-top-level " +
-             "content worker, and wait for their debuggers to be " +
+             "content worker, and wait for their debuggers to be " + 
              "unregistered and closed.");
         promise = waitForMultiple([
           waitForUnregister(CHILD_WORKER_URL),
           waitForDebuggerClose(childDbg),
           waitForUnregister(WORKER_URL),
           waitForDebuggerClose(dbg),
         ]);
         worker.terminate();
         await promise;
 
-        info("Create a shared worker and wait for its debugger to be " +
+        info("Create a shared worker and wait for its debugger to be " + 
              "registered");
         promise = waitForRegister(SHARED_WORKER_URL);
         worker = new SharedWorker(SHARED_WORKER_URL);
         let sharedDbg = await promise;
 
         info("Check that the shared worker debugger has the correct " +
              "properties.");
         is(sharedDbg.isChrome, false,
@@ -89,52 +88,28 @@
              "debugger is not registered again.");
         let listener = {
           onRegistered: function () {
             ok(false,
                "Shared worker debugger should not be registered again.");
           },
         };
         wdm.addListener(listener);
-
         worker = new SharedWorker(SHARED_WORKER_URL);
 
         info("Send a message to the shared worker to tell it to close " +
              "itself, and wait for its debugger to be closed.");
         promise = waitForMultiple([
           waitForUnregister(SHARED_WORKER_URL),
           waitForDebuggerClose(sharedDbg)
         ]);
         worker.port.start();
         worker.port.postMessage("close");
         await promise;
 
-        promise = waitForRegister(SHARED_WORKER_URL);
-        worker = new SharedWorker(SHARED_WORKER_URL);
-        sharedDbg = await promise;
-
-        info("Send a message to the shared worker to tell it to close " +
-             "itself, then loop forever, and wait for its debugger to be closed.");
-        promise = waitForMultiple([
-          waitForUnregister(SHARED_WORKER_URL),
-          waitForDebuggerClose(sharedDbg)
-        ]);
-
-        // When the closing process begins, we schedule a timer to terminate
-        // the worker in case it's in an infinite loop, which is exactly what
-        // we do in this test.  We want a duration long enough that we can be
-        // confident that the infinite loop was entered as measured by
-        // performance.now() and that we terminated it, but not as long as our
-        // 30 second default we currently ship.
-        await SpecialPowers.pushPrefEnv({"set": [[ "dom.worker.canceling.timeoutMilliseconds", 15000 ]]});
-
-        worker.port.start();
-        worker.port.postMessage("close_loop");
-        await promise;
-
         wdm.removeListener(listener);
         SimpleTest.finish();
       })();
     }
 
   ]]>
   </script>
 
--- a/modules/libpref/Preferences.cpp
+++ b/modules/libpref/Preferences.cpp
@@ -4953,22 +4953,16 @@ Preferences::AddAtomicUintVarCache(Atomi
                                    bool);
 
 template nsresult
 Preferences::AddAtomicUintVarCache(Atomic<uint32_t, ReleaseAcquire>*,
                                    const char*,
                                    uint32_t,
                                    bool);
 
-template nsresult
-Preferences::AddAtomicUintVarCache(Atomic<uint32_t, SequentiallyConsistent>*,
-                                   const char*,
-                                   uint32_t,
-                                   bool);
-
 static void
 FloatVarChanged(const char* aPref, void* aClosure)
 {
   CacheData* cache = static_cast<CacheData*>(aClosure);
   *static_cast<float*>(cache->mCacheLocation) =
     Preferences::GetFloat(aPref, cache->mDefaultValueFloat);
 }
 
--- a/testing/web-platform/tests/webmessaging/broadcastchannel/workers.html
+++ b/testing/web-platform/tests/webmessaging/broadcastchannel/workers.html
@@ -116,26 +116,9 @@ async_test(t => {
 
   var w = new Worker(URL.createObjectURL(workerBlob));
   w.onmessage = function(e) {
     assert_true(e.data, "BroadcastChannel created on worker shutdown.");
     t.done();
   }
 }, 'BroadcastChannel created after a worker self.close()');
 
-async_test(t => {
-  function workerCode() {
-    close();
-    var bc = new BroadcastChannel('worker-test-after-close');
-    bc.postMessage(true);
-  }
-
-  var bc = new BroadcastChannel('worker-test-after-close');
-  bc.onmessage = function(e) {
-    assert_true(e.data, "BroadcastChannel created on worker shutdown.");
-    t.done();
-  }
-
-  var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/javascript"});
-  new Worker(URL.createObjectURL(workerBlob));
-}, 'BroadcastChannel used after a worker self.close()');
-
 </script>