Bug 1631618 - Make SharedWorkerService be alive until shutdown r=dom-workers-and-storage-reviewers,asuth a=pascalc
authorEden Chuang <echuang@mozilla.com>
Fri, 15 May 2020 13:49:39 +0000
changeset 591505 f482287318ff33b7ff954172acbae5a2aa7f6137
parent 591504 c958802b0cdf876d236bdf1bfc7c84bf02d5178e
child 591506 7e54014f11535023ffdb6ac56f99712e6b45c188
push id13159
push userarchaeopteryx@coole-files.de
push dateTue, 19 May 2020 14:56:30 +0000
treeherdermozilla-beta@d1a9d96c3989 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdom-workers-and-storage-reviewers, asuth, pascalc
bugs1631618
milestone77.0
Bug 1631618 - Make SharedWorkerService be alive until shutdown r=dom-workers-and-storage-reviewers,asuth a=pascalc Using StaticRefPtr instead of a raw pointer for sSharedWorkerService in SharedWorkerService.cpp, and keeping sSharedWorkerService be alive until shutdown by registering sSharedWorkerService to ClearOnShutdown. Since sSharedWorkerService is not raw pointer anymore, SharedWorkerService needs not to inherit from SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> Differential Revision: https://phabricator.services.mozilla.com/D72379
dom/workers/sharedworkers/SharedWorkerService.cpp
dom/workers/sharedworkers/SharedWorkerService.h
--- a/dom/workers/sharedworkers/SharedWorkerService.cpp
+++ b/dom/workers/sharedworkers/SharedWorkerService.cpp
@@ -2,33 +2,32 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "SharedWorkerService.h"
 #include "mozilla/dom/RemoteWorkerTypes.h"
 #include "mozilla/ipc/BackgroundParent.h"
+#include "mozilla/ClearOnShutdown.h"
 #include "mozilla/SchedulerGroup.h"
 #include "mozilla/StaticMutex.h"
 #include "nsProxyRelease.h"
 
 namespace mozilla {
 
 using namespace ipc;
 
 namespace dom {
 
 namespace {
 
 StaticMutex sSharedWorkerMutex;
 
-// Raw pointer because SharedWorkerParent keeps this object alive, indirectly
-// via SharedWorkerManagerHolder.
-CheckedUnsafePtr<SharedWorkerService> sSharedWorkerService;
+StaticRefPtr<SharedWorkerService> sSharedWorkerService;
 
 class GetOrCreateWorkerManagerRunnable final : public Runnable {
  public:
   GetOrCreateWorkerManagerRunnable(SharedWorkerService* aService,
                                    SharedWorkerParent* aActor,
                                    const RemoteWorkerData& aData,
                                    uint64_t aWindowID,
                                    const MessagePortIdentifier& aPortIdentifier)
@@ -113,47 +112,42 @@ class ErrorPropagationRunnable final : p
 }  // namespace
 
 /* static */
 already_AddRefed<SharedWorkerService> SharedWorkerService::GetOrCreate() {
   AssertIsOnBackgroundThread();
 
   StaticMutexAutoLock lock(sSharedWorkerMutex);
 
-  if (sSharedWorkerService) {
-    RefPtr<SharedWorkerService> instance = sSharedWorkerService.get();
-    return instance.forget();
+  if (!sSharedWorkerService) {
+    sSharedWorkerService = new SharedWorkerService();
+    // ClearOnShutdown can only be called on main thread
+    nsresult rv = SchedulerGroup::Dispatch(
+        TaskCategory::Other,
+        NS_NewRunnableFunction("RegisterSharedWorkerServiceClearOnShutdown",
+                               []() {
+                                 StaticMutexAutoLock lock(sSharedWorkerMutex);
+                                 MOZ_ASSERT(sSharedWorkerService);
+                                 ClearOnShutdown(&sSharedWorkerService);
+                               }));
+    Unused << NS_WARN_IF(NS_FAILED(rv));
   }
 
-  RefPtr<SharedWorkerService> instance = new SharedWorkerService();
+  RefPtr<SharedWorkerService> instance = sSharedWorkerService;
   return instance.forget();
 }
 
 /* static */
 SharedWorkerService* SharedWorkerService::Get() {
   StaticMutexAutoLock lock(sSharedWorkerMutex);
 
   MOZ_ASSERT(sSharedWorkerService);
   return sSharedWorkerService;
 }
 
-SharedWorkerService::SharedWorkerService() {
-  AssertIsOnBackgroundThread();
-
-  MOZ_ASSERT(!sSharedWorkerService);
-  sSharedWorkerService = this;
-}
-
-SharedWorkerService::~SharedWorkerService() {
-  StaticMutexAutoLock lock(sSharedWorkerMutex);
-
-  MOZ_ASSERT(sSharedWorkerService == this);
-  sSharedWorkerService = nullptr;
-}
-
 void SharedWorkerService::GetOrCreateWorkerManager(
     SharedWorkerParent* aActor, const RemoteWorkerData& aData,
     uint64_t aWindowID, const MessagePortIdentifier& aPortIdentifier) {
   AssertIsOnBackgroundThread();
 
   // The real check happens on main-thread.
   RefPtr<GetOrCreateWorkerManagerRunnable> r =
       new GetOrCreateWorkerManagerRunnable(this, aActor, aData, aWindowID,
--- a/dom/workers/sharedworkers/SharedWorkerService.h
+++ b/dom/workers/sharedworkers/SharedWorkerService.h
@@ -20,18 +20,17 @@ class PrincipalInfo;
 namespace dom {
 
 class MessagePortIdentifier;
 class RemoteWorkerData;
 class SharedWorkerManager;
 class SharedWorkerParent;
 class UniqueMessagePortId;
 
-class SharedWorkerService final
-    : public SupportsCheckedUnsafePtr<CheckIf<DiagnosticAssertEnabled>> {
+class SharedWorkerService final {
  public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWorkerService);
 
   // This can be called on PBackground thread only.
   static already_AddRefed<SharedWorkerService> GetOrCreate();
 
   // The service, if already created, is available on any thread using this
   // method.
@@ -46,18 +45,18 @@ class SharedWorkerService final
   void GetOrCreateWorkerManagerOnMainThread(
       nsIEventTarget* aBackgroundEventTarget, SharedWorkerParent* aActor,
       const RemoteWorkerData& aData, uint64_t aWindowID,
       UniqueMessagePortId& aPortIdentifier);
 
   void RemoveWorkerManagerOnMainThread(SharedWorkerManager* aManager);
 
  private:
-  SharedWorkerService();
-  ~SharedWorkerService();
+  SharedWorkerService() = default;
+  ~SharedWorkerService() = default;
 
   void ErrorPropagationOnMainThread(nsIEventTarget* aBackgroundEventTarget,
                                     SharedWorkerParent* aActor,
                                     nsresult aError);
 
   // Touched on main-thread only.
   nsTArray<RefPtr<SharedWorkerManager>> mWorkerManagers;
 };