Bug 1310880 - Add a specialized BackgroundHangMonitor for content process force paints. r?jchen,billm
MozReview-Commit-ID: CccuQRDuaW2
--- a/dom/ipc/ProcessHangMonitor.cpp
+++ b/dom/ipc/ProcessHangMonitor.cpp
@@ -6,16 +6,17 @@
#include "mozilla/ProcessHangMonitor.h"
#include "mozilla/ProcessHangMonitorIPC.h"
#include "jsapi.h"
#include "js/GCAPI.h"
#include "mozilla/Atomics.h"
+#include "mozilla/BackgroundHangMonitor.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/Monitor.h"
#include "mozilla/plugins/PluginBridge.h"
#include "mozilla/Preferences.h"
@@ -110,16 +111,17 @@ class HangMonitorChild
static HangMonitorChild* Get() { return sInstance; }
MessageLoop* MonitorLoop() { return mHangMonitor->MonitorLoop(); }
private:
void ShutdownOnThread();
static Atomic<HangMonitorChild*> sInstance;
+ UniquePtr<BackgroundHangMonitor> mForcePaintMonitor;
const RefPtr<ProcessHangMonitor> mHangMonitor;
Monitor mMonitor;
// Main thread-only.
bool mSentReport;
// These fields must be accessed with mMonitor held.
@@ -272,22 +274,28 @@ HangMonitorChild::HangMonitorChild(Proce
mStartDebugger(false),
mFinishedStartingDebugger(false),
mForcePaint(false),
mShutdownDone(false),
mIPCOpen(true)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
mContext = danger::GetJSContext();
+ mForcePaintMonitor =
+ MakeUnique<mozilla::BackgroundHangMonitor>("Gecko_Child_ForcePaint",
+ 128, /* ms timeout for microhangs */
+ 8192 /* ms timeout for permahangs */,
+ BackgroundHangMonitor::THREAD_PRIVATE);
}
HangMonitorChild::~HangMonitorChild()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sInstance == this);
+ mForcePaintMonitor = nullptr;
sInstance = nullptr;
}
void
HangMonitorChild::InterruptCallback()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@@ -305,16 +313,17 @@ HangMonitorChild::InterruptCallback()
}
if (forcePaint) {
RefPtr<TabChild> tabChild = TabChild::FindTabChild(forcePaintTab);
if (tabChild) {
JS::AutoAssertOnGC nogc(mContext);
JS::AutoAssertOnBarrier nobarrier(mContext);
tabChild->ForcePaint(forcePaintEpoch);
+ mForcePaintMonitor->NotifyWait();
}
}
}
void
HangMonitorChild::Shutdown()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@@ -377,16 +386,18 @@ HangMonitorChild::RecvEndStartingDebugge
return true;
}
bool
HangMonitorChild::RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObserverEpoch)
{
MOZ_RELEASE_ASSERT(MessageLoop::current() == MonitorLoop());
+ mForcePaintMonitor->NotifyActivity();
+
{
MonitorAutoLock lock(mMonitor);
mForcePaint = true;
mForcePaintTab = aTabId;
mForcePaintEpoch = aLayerObserverEpoch;
}
JS_RequestInterruptCallback(mContext);