Bug 1500805 Part 2 - Ensure non-main threads are idle when diverging from the recording, r=mccr8.
--- 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 {