Bug 1731564: Use motivated SpinEventLoopUntil inside dom/*. r?smaug draft
authorJens Stutte <jstutte@mozilla.com>
Mon, 04 Oct 2021 16:16:07 +0000
changeset 4000537 9f013f99a5d9e2ace9c71b11a40297073b21c3dc
parent 4000536 f3d2b5389857315cdb0eaf03fbf78691a9bc5106
child 4000538 97895624fbeb201170a90485796dd2675503f9f7
push id736569
push userreviewbot
push dateMon, 04 Oct 2021 16:17:20 +0000
treeherdertry@6ca418e9f50c [default view] [failures only]
reviewerssmaug
bugs1731564
milestone94.0a1
Bug 1731564: Use motivated SpinEventLoopUntil inside dom/*. r?smaug Summary: Differential Revision: https://phabricator.services.mozilla.com/D126957 Depends on D126714 Test Plan: Reviewers: smaug Subscribers: Bug #: 1731564 Differential Diff: PHID-DIFF-hdnkp4rvqjusaj2jvi7b
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/filehandle/ActorsParent.cpp
dom/indexedDB/ActorsParent.cpp
dom/ipc/ContentChild.cpp
dom/localstorage/LSObject.cpp
dom/media/fuzz/FuzzMedia.cpp
dom/media/gmp/GMPServiceParent.cpp
dom/media/gtest/GMPTestMonitor.h
dom/media/gtest/TestCDMStorage.cpp
dom/media/gtest/TestDriftCompensation.cpp
dom/media/gtest/TestMediaDataDecoder.cpp
dom/media/gtest/TestMediaDataEncoder.cpp
dom/quota/ActorsParent.cpp
dom/storage/StorageObserver.cpp
dom/xhr/XMLHttpRequestMainThread.cpp
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -5040,18 +5040,19 @@ nsGlobalWindowInner::ShowSlowScriptDialo
     }
 
     if (action == ProcessHangMonitor::StartDebugger) {
       // Spin a nested event loop so that the debugger in the parent can fetch
       // any information it needs. Once the debugger has started, return to the
       // script.
       RefPtr<nsGlobalWindowOuter> outer = GetOuterWindowInternal();
       outer->EnterModalState();
-      SpinEventLoopUntil(
-          [&]() { return monitor->IsDebuggerStartupComplete(); });
+      SpinEventLoopUntil("nsGlobalWindowInner::ShowSlowScriptDialog"_ns, [&]() {
+        return monitor->IsDebuggerStartupComplete();
+      });
       outer->LeaveModalState();
       return ContinueSlowScript;
     }
 
     return ContinueSlowScriptAndKeepNotifying;
   }
 
   // Reached only on non-e10s - once per slow script dialog.
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -5433,17 +5433,18 @@ Nullable<WindowProxyHolder> nsGlobalWind
     }
     if (aIsPreview == IsPreview::Yes) {
       return !hasPrintCallbacks;
     }
     return StaticPrefs::dom_window_print_fuzzing_block_while_printing();
   }();
 
   if (shouldBlock) {
-    SpinEventLoopUntil([&] { return bc->IsDiscarded(); });
+    SpinEventLoopUntil("nsGlobalWindowOuter::Print"_ns,
+                       [&] { return bc->IsDiscarded(); });
   }
 
   return WindowProxyHolder(std::move(bc));
 #else
   return nullptr;
 #endif  // NS_PRINTING
 }
 
--- a/dom/filehandle/ActorsParent.cpp
+++ b/dom/filehandle/ActorsParent.cpp
@@ -750,17 +750,18 @@ void FileHandleThreadPool::Shutdown() {
 
   if (!mDirectoryInfos.Count()) {
     Cleanup();
 
     MOZ_ASSERT(mShutdownComplete);
     return;
   }
 
-  MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return mShutdownComplete; }));
+  MOZ_ALWAYS_TRUE(SpinEventLoopUntil("FileHandleThreadPool::Shutdown"_ns,
+                                     [&]() { return mShutdownComplete; }));
 }
 
 nsresult FileHandleThreadPool::Init() {
   AssertIsOnOwningThread();
 
   mThreadPool = new nsThreadPool();
 
   nsresult rv = mThreadPool->SetName("FileHandles"_ns);
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -8119,18 +8119,19 @@ void ConnectionPool::Shutdown() {
     MOZ_ASSERT(!mTransactions.Count());
 
     Cleanup();
 
     MOZ_ASSERT(mShutdownComplete);
     return;
   }
 
-  MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
-      [&]() { return static_cast<bool>(mShutdownComplete); }));
+  MOZ_ALWAYS_TRUE(SpinEventLoopUntil("ConnectionPool::Shutdown"_ns, [&]() {
+    return static_cast<bool>(mShutdownComplete);
+  }));
 }
 
 void ConnectionPool::Cleanup() {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mShutdownRequested);
   MOZ_ASSERT(!mShutdownComplete);
   MOZ_ASSERT(!mDatabases.Count());
   MOZ_ASSERT(!mTransactions.Count());
@@ -8934,30 +8935,31 @@ nsresult ConnectionPool::ThreadRunnable:
 
     if (kDEBUGTransactionThreadSleepMS) {
       NS_WARNING(
           "TransactionThreadPool thread debugging enabled, sleeping "
           "after every event!");
     }
 #endif  // DEBUG
 
-    DebugOnly<bool> b = SpinEventLoopUntil([&]() -> bool {
-      if (!mContinueRunning) {
-        return true;
-      }
-
-#ifdef DEBUG
-      if (kDEBUGTransactionThreadSleepMS) {
-        MOZ_ALWAYS_TRUE(PR_Sleep(PR_MillisecondsToInterval(
-                            kDEBUGTransactionThreadSleepMS)) == PR_SUCCESS);
-      }
+    DebugOnly<bool> b =
+        SpinEventLoopUntil("ConnectionPool::ThreadRunnable"_ns, [&]() -> bool {
+          if (!mContinueRunning) {
+            return true;
+          }
+
+#ifdef DEBUG
+          if (kDEBUGTransactionThreadSleepMS) {
+            MOZ_ALWAYS_TRUE(PR_Sleep(PR_MillisecondsToInterval(
+                                kDEBUGTransactionThreadSleepMS)) == PR_SUCCESS);
+          }
 #endif  // DEBUG
 
-      return false;
-    });
+          return false;
+        });
     // MSVC can't stringify lambdas, so we have to separate the expression
     // generating the value from the assert itself.
 #if DEBUG
     MOZ_ALWAYS_TRUE(b);
 #endif
   }
 
   return NS_OK;
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1219,17 +1219,18 @@ nsresult ContentChild::ProvideWindowComm
     AutoSuppressEventHandlingAndSuspend seh(browsingContext->Group());
 
     AutoNoJSAPI nojsapi;
 
     // Spin the event loop until we get a response. Callers of this function
     // already have to guard against an inner event loop spinning in the
     // non-e10s case because of the need to spin one to create a new chrome
     // window.
-    SpinEventLoopUntil([&]() { return ready; });
+    SpinEventLoopUntil("ContentChild::ProvideWindowCommon"_ns,
+                       [&]() { return ready; });
     MOZ_RELEASE_ASSERT(ready,
                        "We are on the main thread, so we should not exit this "
                        "loop without ready being true.");
   }
 
   // =====================
   // End Nested Event Loop
   // =====================
--- a/dom/localstorage/LSObject.cpp
+++ b/dom/localstorage/LSObject.cpp
@@ -1215,16 +1215,17 @@ nsresult RequestHelper::StartAndReturnRe
             auto helper = static_cast<RequestHelper*>(aClosure);
 
             helper->mCancelled = true;
           },
           this, FAILSAFE_CANCEL_SYNC_OP_MS, nsITimer::TYPE_ONE_SHOT,
           "RequestHelper::StartAndReturnResponse::SpinEventLoopTimer"));
 
       MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+          "RequestHelper::StartAndReturnResponse"_ns,
           [&]() {
             if (mCancelled) {
               return true;
             }
 
             if (!mWaiting) {
               return true;
             }
--- a/dom/media/fuzz/FuzzMedia.cpp
+++ b/dom/media/fuzz/FuzzMedia.cpp
@@ -31,17 +31,17 @@ class FuzzRunner {
     mBenchmark->Init();
     mBenchmark->Run()->Then(
         // Non DocGroup-version of AbstractThread::MainThread() is fine for
         // testing.
         AbstractThread::MainThread(), __func__,
         [&](uint32_t aDecodeFps) { done = true; }, [&]() { done = true; });
 
     // Wait until benchmark completes.
-    SpinEventLoopUntil([&]() { return done; });
+    SpinEventLoopUntil("FuzzRunner::Run"_ns, [&]() { return done; });
     return;
   }
 
  private:
   RefPtr<Benchmark> mBenchmark;
 };
 
 #define MOZ_MEDIA_FUZZER(_name)                                         \
--- a/dom/media/gmp/GMPServiceParent.cpp
+++ b/dom/media/gmp/GMPServiceParent.cpp
@@ -272,17 +272,20 @@ GeckoMediaPluginServiceParent::Observe(n
           __CLASS__, __FUNCTION__);
       gmpThread->Dispatch(
           NewRunnableMethod("gmp::GeckoMediaPluginServiceParent::UnloadPlugins",
                             this,
                             &GeckoMediaPluginServiceParent::UnloadPlugins),
           NS_DISPATCH_NORMAL);
 
       // Wait for UnloadPlugins() to do sync shutdown...
-      SpinEventLoopUntil([&]() { return !mWaitingForPluginsSyncShutdown; });
+      SpinEventLoopUntil(
+          "GeckoMediaPluginServiceParent::Observe "
+          "WaitingForPluginsSyncShutdown"_ns,
+          [&]() { return !mWaitingForPluginsSyncShutdown; });
     } else {
       // GMP thread has already shutdown.
       MOZ_ASSERT(mPlugins.IsEmpty());
       mWaitingForPluginsSyncShutdown = false;
     }
 
   } else if (!strcmp(NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID, aTopic)) {
     MOZ_ASSERT(mShuttingDown);
--- a/dom/media/gtest/GMPTestMonitor.h
+++ b/dom/media/gtest/GMPTestMonitor.h
@@ -11,17 +11,18 @@
 #include "mozilla/SpinEventLoopUntil.h"
 
 class GMPTestMonitor {
  public:
   GMPTestMonitor() : mFinished(false) {}
 
   void AwaitFinished() {
     MOZ_ASSERT(NS_IsMainThread());
-    mozilla::SpinEventLoopUntil([&]() { return mFinished; });
+    mozilla::SpinEventLoopUntil("GMPTestMonitor::AwaitFinished"_ns,
+                                [&]() { return mFinished; });
     mFinished = false;
   }
 
  private:
   void MarkFinished() {
     MOZ_ASSERT(NS_IsMainThread());
     mFinished = true;
   }
--- a/dom/media/gtest/TestCDMStorage.cpp
+++ b/dom/media/gtest/TestCDMStorage.cpp
@@ -1071,17 +1071,18 @@ class CDMStorageTest {
 
   void Expect(const nsCString& aMessage,
               already_AddRefed<nsIRunnable> aContinuation) {
     mExpected.AppendElement(
         ExpectedMessage(aMessage, std::move(aContinuation)));
   }
 
   void AwaitFinished() {
-    mozilla::SpinEventLoopUntil([&]() -> bool { return mFinished; });
+    mozilla::SpinEventLoopUntil("CDMStorageTest::AwaitFinished"_ns,
+                                [&]() -> bool { return mFinished; });
     mFinished = false;
   }
 
   void ShutdownThen(already_AddRefed<nsIRunnable> aContinuation) {
     EXPECT_TRUE(!!mCDM);
     if (!mCDM) {
       return;
     }
--- a/dom/media/gtest/TestDriftCompensation.cpp
+++ b/dom/media/gtest/TestDriftCompensation.cpp
@@ -22,17 +22,18 @@ class DriftCompensatorTest : public ::te
     mComp->NotifyAudioStart(mStart);
     // NotifyAudioStart dispatched a runnable to update the audio mStart time on
     // the video thread. Because this is a test, the video thread is the current
     // thread. We spin the event loop until we know the mStart time is updated.
     {
       bool updated = false;
       NS_DispatchToCurrentThread(
           NS_NewRunnableFunction(__func__, [&] { updated = true; }));
-      SpinEventLoopUntil([&] { return updated; });
+      SpinEventLoopUntil("DriftCompensatorTest::DriftCompensatorTest"_ns,
+                         [&] { return updated; });
     }
   }
 
   // Past() is half as far from `mStart` as `aNow`.
   TimeStamp Past(TimeStamp aNow) {
     return mStart + (aNow - mStart) / (int64_t)2;
   }
 
--- a/dom/media/gtest/TestMediaDataDecoder.cpp
+++ b/dom/media/gtest/TestMediaDataDecoder.cpp
@@ -32,17 +32,17 @@ class BenchmarkRunner {
         AbstractThread::MainThread(), __func__,
         [&](uint32_t aDecodeFps) {
           result = aDecodeFps;
           done = true;
         },
         [&]() { done = true; });
 
     // Wait until benchmark completes.
-    SpinEventLoopUntil([&]() { return done; });
+    SpinEventLoopUntil("BenchmarkRunner::Run"_ns, [&]() { return done; });
     return result;
   }
 
  private:
   RefPtr<Benchmark> mBenchmark;
 };
 
 TEST(MediaDataDecoder, H264)
--- a/dom/media/gtest/TestMediaDataEncoder.cpp
+++ b/dom/media/gtest/TestMediaDataEncoder.cpp
@@ -193,17 +193,18 @@ void WaitForShutdown(RefPtr<MediaDataEnc
       [&result](bool rv) {
         EXPECT_TRUE(rv);
         result = Some(true);
       },
       [&result]() {
         FAIL() << "Shutdown should never be rejected";
         result = Some(false);
       });
-  SpinEventLoopUntil([&result]() { return result; });
+  SpinEventLoopUntil("TestMediaDataEncoder.cpp:WaitForShutdown"_ns,
+                     [&result]() { return result; });
 }
 
 TEST_F(MediaDataEncoderTest, H264Create) {
   RUN_IF_SUPPORTED(VIDEO_MP4, []() {
     RefPtr<MediaDataEncoder> e = CreateH264Encoder();
     EXPECT_TRUE(e);
     WaitForShutdown(e);
   });
@@ -399,33 +400,33 @@ TEST_F(MediaDataEncoderTest, VP8Inits) {
 TEST_F(MediaDataEncoderTest, VP8Encodes) {
   RUN_IF_SUPPORTED(VIDEO_VP8, [this]() {
     // Encode one VPX frame.
     RefPtr<MediaDataEncoder> e = CreateVP8Encoder();
     EnsureInit(e);
     MediaDataEncoder::EncodedData output = Encode(e, 1UL, mData);
     EXPECT_EQ(output.Length(), 1UL);
     VPXDecoder::VPXStreamInfo info;
-    EXPECT_TRUE(VPXDecoder::GetStreamInfo(*output[0], info,
-                                          VPXDecoder::Codec::VP8));
+    EXPECT_TRUE(
+        VPXDecoder::GetStreamInfo(*output[0], info, VPXDecoder::Codec::VP8));
     EXPECT_EQ(info.mKeyFrame, output[0]->mKeyframe);
     if (info.mKeyFrame) {
       EXPECT_EQ(info.mImage, kImageSize);
     }
     WaitForShutdown(e);
 
     // Encode multiple VPX frames.
     e = CreateVP8Encoder();
     EnsureInit(e);
     output = Encode(e, NUM_FRAMES, mData);
     EXPECT_EQ(output.Length(), NUM_FRAMES);
     for (auto frame : output) {
       VPXDecoder::VPXStreamInfo info;
-      EXPECT_TRUE(VPXDecoder::GetStreamInfo(*frame, info,
-                                            VPXDecoder::Codec::VP8));
+      EXPECT_TRUE(
+          VPXDecoder::GetStreamInfo(*frame, info, VPXDecoder::Codec::VP8));
       EXPECT_EQ(info.mKeyFrame, frame->mKeyframe);
       if (info.mKeyFrame) {
         EXPECT_EQ(info.mImage, kImageSize);
       }
     }
     WaitForShutdown(e);
   });
 }
@@ -456,32 +457,32 @@ TEST_F(MediaDataEncoderTest, VP9Inits) {
 
 TEST_F(MediaDataEncoderTest, VP9Encodes) {
   RUN_IF_SUPPORTED(VIDEO_VP9, [this]() {
     RefPtr<MediaDataEncoder> e = CreateVP9Encoder();
     EnsureInit(e);
     MediaDataEncoder::EncodedData output = Encode(e, 1UL, mData);
     EXPECT_EQ(output.Length(), 1UL);
     VPXDecoder::VPXStreamInfo info;
-    EXPECT_TRUE(VPXDecoder::GetStreamInfo(*output[0], info,
-                                          VPXDecoder::Codec::VP9));
+    EXPECT_TRUE(
+        VPXDecoder::GetStreamInfo(*output[0], info, VPXDecoder::Codec::VP9));
     EXPECT_EQ(info.mKeyFrame, output[0]->mKeyframe);
     if (info.mKeyFrame) {
       EXPECT_EQ(info.mImage, kImageSize);
     }
     WaitForShutdown(e);
 
     e = CreateVP9Encoder();
     EnsureInit(e);
     output = Encode(e, NUM_FRAMES, mData);
     EXPECT_EQ(output.Length(), NUM_FRAMES);
     for (auto frame : output) {
       VPXDecoder::VPXStreamInfo info;
-      EXPECT_TRUE(VPXDecoder::GetStreamInfo(*frame, info,
-                                            VPXDecoder::Codec::VP9));
+      EXPECT_TRUE(
+          VPXDecoder::GetStreamInfo(*frame, info, VPXDecoder::Codec::VP9));
       EXPECT_EQ(info.mKeyFrame, frame->mKeyframe);
       if (info.mKeyFrame) {
         EXPECT_EQ(info.mImage, kImageSize);
       }
     }
     WaitForShutdown(e);
   });
 }
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -2933,17 +2933,19 @@ QuotaManager::Observer::Observe(nsISuppo
     if (NS_WARN_IF(!backgroundActor)) {
       return NS_ERROR_FAILURE;
     }
 
     if (NS_WARN_IF(!backgroundActor->SendShutdownQuotaManager())) {
       return NS_ERROR_FAILURE;
     }
 
-    MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return mShutdownComplete; }));
+    MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+        "QuotaManager::Observer::Observe profile-before-change-qm"_ns,
+        [&]() { return mShutdownComplete; }));
 
     gBasePath = nullptr;
 
     gStorageName = nullptr;
 
     gBuildId = nullptr;
 
     Telemetry::SetEventRecordingEnabled("dom.quota.try"_ns, false);
@@ -3877,23 +3879,25 @@ void QuotaManager::Shutdown() {
                       },
                       aClosure, SHUTDOWN_FORCE_CRASH_TIMEOUT_MS,
                       nsITimer::TYPE_ONE_SHOT,
                       "quota::QuotaManager::ForceCrashTimer"));
                 },
                 this, SHUTDOWN_FORCE_KILL_TIMEOUT_MS, nsITimer::TYPE_ONE_SHOT,
                 "quota::QuotaManager::ForceKillTimer"));
 
-    MOZ_ALWAYS_TRUE(SpinEventLoopUntil([this, &allClientTypes] {
-      return !gNormalOriginOps &&
-             std::all_of(allClientTypes.cbegin(), allClientTypes.cend(),
-                         [&self = *this](const auto type) {
-                           return (*self.mClients)[type]->IsShutdownCompleted();
-                         });
-    }));
+    MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+        "QuotaManager::Shutdown"_ns, [this, &allClientTypes] {
+          return !gNormalOriginOps &&
+                 std::all_of(
+                     allClientTypes.cbegin(), allClientTypes.cend(),
+                     [&self = *this](const auto type) {
+                       return (*self.mClients)[type]->IsShutdownCompleted();
+                     });
+        }));
   }
 
   for (Client::Type type : allClientTypes) {
     (*mClients)[type]->FinalizeShutdownWorkThreads();
   }
 
   // Cancel the timer regardless of whether it actually fired.
   QM_WARNONLY_TRY(QM_TO_RESULT((*mShutdownTimer)->Cancel()));
--- a/dom/storage/StorageObserver.cpp
+++ b/dom/storage/StorageObserver.cpp
@@ -444,17 +444,19 @@ StorageObserver::Observe(nsISupports* aS
       if (mBackgroundThread[id]) {
         bool done = false;
 
         RefPtr<StorageDBThread::ShutdownRunnable> shutdownRunnable =
             new StorageDBThread::ShutdownRunnable(id, done);
         MOZ_ALWAYS_SUCCEEDS(mBackgroundThread[id]->Dispatch(
             shutdownRunnable, NS_DISPATCH_NORMAL));
 
-        MOZ_ALWAYS_TRUE(SpinEventLoopUntil([&]() { return done; }));
+        MOZ_ALWAYS_TRUE(SpinEventLoopUntil(
+            "StorageObserver::Observe profile-before-change"_ns,
+            [&]() { return done; }));
 
         mBackgroundThread[id] = nullptr;
       }
     }
 
     return NS_OK;
   }
 
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -3055,17 +3055,18 @@ void XMLHttpRequestMainThread::SendInter
     if (syncTimeoutType == eErrorOrExpired) {
       Abort();
       aRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
       return;
     }
 
     nsAutoSyncOperation sync(suspendedDoc,
                              SyncOperationBehavior::eSuspendInput);
-    if (!SpinEventLoopUntil([&]() { return !mFlagSyncLooping; })) {
+    if (!SpinEventLoopUntil("XMLHttpRequestMainThread::SendInternal"_ns,
+                            [&]() { return !mFlagSyncLooping; })) {
       aRv.Throw(NS_ERROR_UNEXPECTED);
       return;
     }
 
     // Time expired... We should throw.
     if (syncTimeoutType == eTimerStarted && !mSyncTimeoutTimer) {
       aRv.Throw(NS_ERROR_DOM_NETWORK_ERR);
       return;