Bug 1443329 - Ensure we always call NotifyActivity on ForcePaint BHR r=mconley

MozReview-Commit-ID: GomQWREr7vG

--HG--
extra : rebase_source : 3df24e9c23b079f196b378559b0cb8536736a7a2
This commit is contained in:
Doug Thayer 2018-03-18 11:44:19 -07:00
parent c3b437237a
commit 4b5dac8a83
3 changed files with 44 additions and 1 deletions

View File

@ -97,6 +97,12 @@ class HangMonitorChild
void ClearHangAsync();
void ClearForcePaint(uint64_t aLayerObserverEpoch);
// MaybeStartForcePaint will notify the background hang monitor of activity
// if this is the first time calling it since ClearForcePaint. It should be
// callable from any thread, but you must be holding mMonitor if using it off
// the main thread, since it could race with ClearForcePaint.
void MaybeStartForcePaint();
mozilla::ipc::IPCResult RecvTerminateScript(const bool& aTerminateGlobal) override;
mozilla::ipc::IPCResult RecvBeginStartingDebugger() override;
mozilla::ipc::IPCResult RecvEndStartingDebugger() override;
@ -141,6 +147,10 @@ class HangMonitorChild
// This field is only accessed on the hang thread.
bool mIPCOpen;
// Allows us to ensure we NotifyActivity only once, allowing
// either thread to do so.
Atomic<bool> mBHRMonitorActive;
};
Atomic<HangMonitorChild*> HangMonitorChild::sInstance;
@ -430,7 +440,7 @@ HangMonitorChild::RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObse
if (mForcePaintEpoch >= aLayerObserverEpoch) {
return IPC_OK();
}
mForcePaintMonitor->NotifyActivity();
MaybeStartForcePaint();
mForcePaint = true;
mForcePaintTab = aTabId;
mForcePaintEpoch = aLayerObserverEpoch;
@ -441,6 +451,18 @@ HangMonitorChild::RecvForcePaint(const TabId& aTabId, const uint64_t& aLayerObse
return IPC_OK();
}
void
HangMonitorChild::MaybeStartForcePaint()
{
if (!NS_IsMainThread()) {
mMonitor.AssertCurrentThreadOwns();
}
if (!mBHRMonitorActive.exchange(true)) {
mForcePaintMonitor->NotifyActivity();
}
}
void
HangMonitorChild::ClearForcePaint(uint64_t aLayerObserverEpoch)
{
@ -457,6 +479,11 @@ HangMonitorChild::ClearForcePaint(uint64_t aLayerObserverEpoch)
mForcePaintEpoch = aLayerObserverEpoch;
}
mForcePaintMonitor->NotifyWait();
// ClearForcePaint must be called on the main thread, and the
// hang monitor thread only sets this with mMonitor held, so there
// should be no risk of missing NotifyActivity calls here.
mBHRMonitorActive = false;
}
}
@ -1381,3 +1408,14 @@ ProcessHangMonitor::ClearForcePaint(uint64_t aLayerObserverEpoch)
child->ClearForcePaint(aLayerObserverEpoch);
}
}
/* static */ void
ProcessHangMonitor::MaybeStartForcePaint()
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(XRE_IsContentProcess());
if (HangMonitorChild* child = HangMonitorChild::Get()) {
child->MaybeStartForcePaint();
}
}

View File

@ -49,6 +49,7 @@ class ProcessHangMonitor final
dom::TabParent* aTab,
uint64_t aLayerObserverEpoch);
static void ClearForcePaint(uint64_t aLayerObserverEpoch);
static void MaybeStartForcePaint();
enum SlowScriptAction {
Continue,

View File

@ -2584,6 +2584,10 @@ TabChild::RecvRenderLayers(const bool& aEnabled, const uint64_t& aLayerObserverE
}
});
if (aEnabled) {
ProcessHangMonitor::MaybeStartForcePaint();
}
if (mCompositorOptions) {
MOZ_ASSERT(mPuppetWidget);
RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();