author | Brian Hackett <bhackett1024@gmail.com> |
Tue, 14 Aug 2018 00:30:09 +0000 | |
changeset 489174 | 3352ce18917b2c7d210cc09aa1b610c2ca775580 |
parent 489173 | d492e85d1040e12a5b34c25a45156e02d91d22fe |
child 489175 | 290b508c04ee871a1582f4ede10ed1d6ed2cc8dd |
push id | 1815 |
push user | ffxbld-merge |
push date | Mon, 15 Oct 2018 10:40:45 +0000 |
treeherder | mozilla-release@18d4c09e9378 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8 |
bugs | 1481346 |
milestone | 63.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
|
--- a/ipc/glue/MessageChannel.cpp +++ b/ipc/glue/MessageChannel.cpp @@ -2185,17 +2185,20 @@ void MessageChannel::DispatchSyncMessage(const Message& aMsg, Message*& aReply) { AssertWorkerThread(); mozilla::TimeStamp start = TimeStamp::Now(); int nestedLevel = aMsg.nested_level(); - MOZ_RELEASE_ASSERT(nestedLevel == IPC::Message::NOT_NESTED || NS_IsMainThread()); + MOZ_RELEASE_ASSERT(nestedLevel == IPC::Message::NOT_NESTED || + NS_IsMainThread() || + // Middleman processes forward sync messages on a non-main thread. + recordreplay::IsMiddleman()); #ifdef MOZ_TASK_TRACER AutoScopedLabel autolabel("sync message %s", aMsg.name()); #endif MessageChannel* dummy; MessageChannel*& blockingVar = mSide == ChildSide && NS_IsMainThread() ? gParentProcessBlocker : dummy; Result rv;
--- a/toolkit/recordreplay/ipc/ChildProcess.cpp +++ b/toolkit/recordreplay/ipc/ChildProcess.cpp @@ -642,18 +642,20 @@ void ChildProcessInfo::WaitUntil(const std::function<bool()>& aCallback) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); bool sentTerminateMessage = false; while (!aCallback()) { MonitorAutoLock lock(*gMonitor); if (!MaybeProcessPendingMessage(this)) { - if (gChildrenAreDebugging) { - // Don't watch for hangs when children are being debugged. + if (gChildrenAreDebugging || IsRecording()) { + // Don't watch for hangs when children are being debugged. Recording + // children are never treated as hanged both because they cannot be + // restarted and because they may just be idling. gMonitor->Wait(); } else { TimeStamp deadline = mLastMessageTime + TimeDuration::FromSeconds(HangSeconds); if (TimeStamp::Now() >= deadline) { MonitorAutoUnlock unlock(*gMonitor); if (!sentTerminateMessage) { // Try to get the child to crash, so that we can get a minidump. // Sending the message will reset mLastMessageTime so we get to
--- a/toolkit/recordreplay/ipc/ParentForwarding.cpp +++ b/toolkit/recordreplay/ipc/ParentForwarding.cpp @@ -169,16 +169,17 @@ MainThreadIsWaitingForIPDLReply() // Helper for places where the main thread will block while waiting on a // synchronous IPDL reply from a child process. Incoming messages from the // child must be handled immediately. struct MOZ_RAII AutoMarkMainThreadWaitingForIPDLReply { AutoMarkMainThreadWaitingForIPDLReply() { MOZ_RELEASE_ASSERT(NS_IsMainThread()); MOZ_RELEASE_ASSERT(!gMainThreadIsWaitingForIPDLReply); + ResumeBeforeWaitingForIPDLReply(); gMainThreadIsWaitingForIPDLReply = true; } ~AutoMarkMainThreadWaitingForIPDLReply() { gMainThreadIsWaitingForIPDLReply = false; } };
--- a/toolkit/recordreplay/ipc/ParentIPC.cpp +++ b/toolkit/recordreplay/ipc/ParentIPC.cpp @@ -1086,16 +1086,30 @@ ResumeForwardOrBackward() { MOZ_RELEASE_ASSERT(!gChildExecuteForward || !gChildExecuteBackward); if (gResumeForwardOrBackward && (gChildExecuteForward || gChildExecuteBackward)) { Resume(gChildExecuteForward); } } +void +ResumeBeforeWaitingForIPDLReply() +{ + MOZ_RELEASE_ASSERT(gActiveChild->IsRecording()); + + // The main thread is about to block while it waits for a sync reply from the + // recording child process. If the child is paused, resume it immediately so + // that we don't deadlock. + if (gActiveChild->IsPaused()) { + MOZ_RELEASE_ASSERT(gChildExecuteForward); + Resume(true); + } +} + static void RecvHitCheckpoint(const HitCheckpointMessage& aMsg) { UpdateCheckpointTimes(aMsg); // Resume either forwards or backwards. Break the resume off into a separate // runnable, to avoid starving any code already on the stack and waiting for // the process to pause. Immediately resume if the main thread is blocked.
--- a/toolkit/recordreplay/ipc/ParentInternal.h +++ b/toolkit/recordreplay/ipc/ParentInternal.h @@ -36,16 +36,20 @@ bool ActiveChildIsRecording(); // Get the active recording child process. ChildProcessInfo* ActiveRecordingChild(); // Return whether the middleman's main thread is blocked waiting on a // synchronous IPDL reply from the recording child. bool MainThreadIsWaitingForIPDLReply(); +// If necessary, resume execution in the child before the main thread begins +// to block while waiting on an IPDL reply from the child. +void ResumeBeforeWaitingForIPDLReply(); + // Initialize state which handles incoming IPDL messages from the UI and // recording child processes. void InitializeForwarding(); // Terminate all children and kill this process. void Shutdown(); // Monitor used for synchronizing between the main and channel or message loop threads.