Bug 1602393: Fake ShutdownComplete() for all error conditions of ServiceWorkerRegistrar::ProfileStopped. r=dom-worker-reviewers,jesup
authorJens Stutte <jstutte@mozilla.com>
Mon, 23 May 2022 14:43:29 +0000
changeset 618545 099bc1f51e2f061fc27b4c337fbea713b8a3dbbe
parent 618544 c9a7cf183046b2582dd95725d74223c555f6d48d
child 618546 a3e657cb7f55e0da33d84cfd0c188fb77436834a
push id163326
push userjstutte@mozilla.com
push dateMon, 23 May 2022 14:45:50 +0000
treeherderautoland@099bc1f51e2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdom-worker-reviewers, jesup
bugs1602393
milestone102.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 1602393: Fake ShutdownComplete() for all error conditions of ServiceWorkerRegistrar::ProfileStopped. r=dom-worker-reviewers,jesup Differential Revision: https://phabricator.services.mozilla.com/D146301
dom/serviceworkers/ServiceWorkerRegistrar.cpp
--- a/dom/serviceworkers/ServiceWorkerRegistrar.cpp
+++ b/dom/serviceworkers/ServiceWorkerRegistrar.cpp
@@ -1307,58 +1307,63 @@ void ServiceWorkerRegistrar::ProfileStop
   MOZ_ASSERT(NS_IsMainThread());
 
   MonitorAutoLock lock(mMonitor);
 
   if (!mProfileDir) {
     nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
                                          getter_AddRefs(mProfileDir));
     if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
+      // If we do not have a profile directory, we are somehow screwed.
+      MOZ_DIAGNOSTIC_ASSERT(
+          false,
+          "NS_GetSpecialDirectory for NS_APP_USER_PROFILE_50_DIR failed!");
     }
   }
 
+  // Mutations to the ServiceWorkerRegistrar happen on the PBackground thread,
+  // issued by the ServiceWorkerManagerService, so the appropriate place to
+  // trigger shutdown is on that thread.
+  //
+  // However, it's quite possible that the PBackground thread was not brought
+  // into existence for xpcshell tests.  We don't cause it to be created
+  // ourselves for any reason, for example.
+  //
+  // In this scenario, we know that:
+  // - We will receive exactly one call to ourself from BlockShutdown() and
+  //   BlockShutdown() will be called (at most) once.
+  // - The only way our Shutdown() method gets called is via
+  //   BackgroundParentImpl::RecvShutdownServiceWorkerRegistrar() being
+  //   invoked, which only happens if we get to that send below here that we
+  //   can't get to.
+  // - All Shutdown() does is set mShuttingDown=true (essential for
+  //   invariants) and invoke MaybeScheduleShutdownCompleted().
+  // - Since there is no PBackground thread, mSaveDataRunnableDispatched must
+  //   be false because only MaybeScheduleSaveData() set it and it only runs
+  //   on the background thread, so it cannot have run.  And so we would
+  //   expect MaybeScheduleShutdownCompleted() to schedule an invocation of
+  //   ShutdownCompleted on the main thread.
   PBackgroundChild* child = BackgroundChild::GetForCurrentThread();
-  if (!child) {
-    // Mutations to the ServiceWorkerRegistrar happen on the PBackground thread,
-    // issued by the ServiceWorkerManagerService, so the appropriate place to
-    // trigger shutdown is on that thread.
-    //
-    // However, it's quite possible that the PBackground thread was not brought
-    // into existence for xpcshell tests.  We don't cause it to be created
-    // ourselves for any reason, for example.
-    //
-    // In this scenario, we know that:
-    // - We will receive exactly one call to ourself from BlockShutdown() and
-    //   BlockShutdown() will be called (at most) once.
-    // - The only way our Shutdown() method gets called is via
-    //   BackgroundParentImpl::RecvShutdownServiceWorkerRegistrar() being
-    //   invoked, which only happens if we get to that send below here that we
-    //   can't get to.
-    // - All Shutdown() does is set mShuttingDown=true (essential for
-    //   invariants) and invoke MaybeScheduleShutdownCompleted().
-    // - Since there is no PBackground thread, mSaveDataRunnableDispatched must
-    //   be false because only MaybeScheduleSaveData() set it and it only runs
-    //   on the background thread, so it cannot have run.  And so we would
-    //   expect MaybeScheduleShutdownCompleted() to schedule an invocation of
-    //   ShutdownCompleted on the main thread.
-    //
-    // So it's appropriate for us to set mShuttingDown=true (as Shutdown would
-    // do) and directly invoke ShutdownCompleted() (as Shutdown would indirectly
-    // do via MaybeScheduleShutdownCompleted).
-    mShuttingDown = true;
-    ShutdownCompleted();
-    return;
+  if (mProfileDir && child) {
+    if (child->SendShutdownServiceWorkerRegistrar()) {
+      // Normal shutdown sequence has been initiated, go home.
+      return;
+    }
+    // If we get here, the PBackground thread has probably gone nuts and we
+    // want to know it.
+    MOZ_DIAGNOSTIC_ASSERT(
+        false, "Unable to send the ShutdownServiceWorkerRegistrar message.");
   }
 
-  if (!child->SendShutdownServiceWorkerRegistrar()) {
-    // If we get here, the PBackground thread has probably gone nuts and we
-    // want to know it. We could try to mitigate as above for xpcshell.
-    MOZ_CRASH("Unable to send the ShutdownServiceWorkerRegistrar message.");
-  }
+  // On any error it's appropriate to set mShuttingDown=true (as Shutdown
+  // would do) and directly invoke ShutdownCompleted() (as Shutdown would
+  // indirectly do via MaybeScheduleShutdownCompleted) in order to unblock
+  // shutdown.
+  mShuttingDown = true;
+  ShutdownCompleted();
 }
 
 // Async shutdown blocker methods
 
 NS_IMETHODIMP
 ServiceWorkerRegistrar::BlockShutdown(nsIAsyncShutdownClient* aClient) {
   ProfileStopped();
   return NS_OK;