Bug 1500805 Part 2 - Ensure non-main threads are idle when diverging from the recording, r=mccr8.
authorBrian Hackett <bhackett1024@gmail.com>
Sun, 21 Oct 2018 15:02:32 -0600
changeset 491287 20691f6e5da854dabedc2c2beb97133599cec868
parent 491286 25e1e5dcacb2d8a968167ba7e3775e1fcd862590
child 491288 ac631ceaa2b95d5c44f470cffba8bd1b339b0403
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersmccr8
bugs1500805
milestone65.0a1
Bug 1500805 Part 2 - Ensure non-main threads are idle when diverging from the recording, r=mccr8.
toolkit/recordreplay/ProcessRewind.cpp
toolkit/recordreplay/ipc/ChildIPC.cpp
--- a/toolkit/recordreplay/ProcessRewind.cpp
+++ b/toolkit/recordreplay/ProcessRewind.cpp
@@ -194,16 +194,21 @@ DivergeFromRecording()
 
   Thread* thread = Thread::Current();
   MOZ_RELEASE_ASSERT(thread->IsMainThread());
 
   if (!thread->HasDivergedFromRecording()) {
     // Reset middleman call state whenever we first diverge from the recording.
     child::SendResetMiddlemanCalls();
 
+    // Make sure all non-main threads are idle before we begin diverging. This
+    // thread's new behavior can change values used by other threads and induce
+    // recording mismatches.
+    Thread::WaitForIdleThreads();
+
     thread->DivergeFromRecording();
   }
 
   gUnhandledDivergeAllowed = true;
 }
 
 extern "C" {
 
--- a/toolkit/recordreplay/ipc/ChildIPC.cpp
+++ b/toolkit/recordreplay/ipc/ChildIPC.cpp
@@ -572,32 +572,31 @@ Repaint(size_t* aWidth, size_t* aHeight)
     return;
   }
 
   // Ignore the request to repaint if the compositor thread has already
   // diverged from the recording. In this case we have already done a repaint
   // and the last graphics we sent will still be correct.
   Thread* compositorThread = Thread::GetById(gCompositorThreadId);
   if (!compositorThread->WillDivergeFromRecordingSoon()) {
+    // Allow the compositor to diverge from the recording so it can perform
+    // any paint we are about to trigger, or finish any in flight paint that
+    // that existed at the point we are paused at.
+    Thread::GetById(gCompositorThreadId)->SetShouldDivergeFromRecording();
+    Thread::ResumeSingleIdleThread(gCompositorThreadId);
+
     // Create an artifical vsync to see if graphics have changed since the last
     // paint and a new paint is needed.
     NotifyVsyncObserver();
 
-    if (gNumPendingPaints) {
-      // Allow the compositor to diverge from the recording so it can perform
-      // any paint we just triggered, or finish any in flight paint that that
-      // existed at the point we are paused at.
-      Thread::GetById(gCompositorThreadId)->SetShouldDivergeFromRecording();
-
-      // Wait for the compositor to finish all in flight paints, including any
-      // one we just triggered.
-      MonitorAutoLock lock(*gMonitor);
-      while (gNumPendingPaints) {
-        gMonitor->Wait();
-      }
+    // Wait for the compositor to finish all in flight paints, including any
+    // one we just triggered.
+    MonitorAutoLock lock(*gMonitor);
+    while (gNumPendingPaints) {
+      gMonitor->Wait();
     }
   }
 
   if (gDrawTargetBuffer) {
     memcpy(gGraphicsShmem, gDrawTargetBuffer, gDrawTargetBufferSize);
     *aWidth = gPaintWidth;
     *aHeight = gPaintHeight;
   } else {