Bug 1384238 - Annotate BHR hangs which occur while there is a pending input event, r=smaug
MozReview-Commit-ID: HRPMw2IfEKB
This commit is contained in:
@@ -10686,6 +10686,29 @@ nsContentUtils::GetSourceMapURL(nsIHttpChannel* aChannel, nsACString& aResult)
|
|||||||
return NS_SUCCEEDED(rv);
|
return NS_SUCCEEDED(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ bool
|
||||||
|
nsContentUtils::IsMessageInputEvent(const IPC::Message& aMsg)
|
||||||
|
{
|
||||||
|
if ((aMsg.type() & mozilla::dom::PBrowser::PBrowserStart)
|
||||||
|
== mozilla::dom::PBrowser::PBrowserStart) {
|
||||||
|
switch (aMsg.type()) {
|
||||||
|
case mozilla::dom::PBrowser::Msg_RealMouseMoveEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_RealMouseButtonEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_RealKeyEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_MouseWheelEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_RealTouchEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_RealTouchMoveEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_RealDragEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_UpdateDimensions__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_MouseEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_KeyEvent__ID:
|
||||||
|
case mozilla::dom::PBrowser::Msg_SetDocShellIsActive__ID:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* kUserInteractionInactive = "user-interaction-inactive";
|
static const char* kUserInteractionInactive = "user-interaction-inactive";
|
||||||
static const char* kUserInteractionActive = "user-interaction-active";
|
static const char* kUserInteractionActive = "user-interaction-active";
|
||||||
|
|
||||||
|
|||||||
@@ -3126,6 +3126,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool GetSourceMapURL(nsIHttpChannel* aChannel, nsACString& aResult);
|
static bool GetSourceMapURL(nsIHttpChannel* aChannel, nsACString& aResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the passed-in mesasge is a pending InputEvent.
|
||||||
|
*
|
||||||
|
* @param aMsg The message to check
|
||||||
|
*/
|
||||||
|
static bool IsMessageInputEvent(const IPC::Message& aMsg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool InitializeEventTable();
|
static bool InitializeEventTable();
|
||||||
|
|
||||||
|
|||||||
@@ -491,6 +491,29 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
/**
|
||||||
|
* The singleton of this class is registered with the HangMonitor as an
|
||||||
|
* annotator, so that the hang monitor can record whether or not there were
|
||||||
|
* pending input events when the thread hung.
|
||||||
|
*/
|
||||||
|
class PendingInputEventHangAnnotator final
|
||||||
|
: public HangMonitor::Annotator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void AnnotateHang(HangMonitor::HangAnnotations& aAnnotations)
|
||||||
|
{
|
||||||
|
int32_t pending = ContentChild::GetSingleton()->GetPendingInputEvents();
|
||||||
|
if (pending > 0) {
|
||||||
|
aAnnotations.AddAnnotation(NS_LITERAL_STRING("PendingInput"), pending);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static PendingInputEventHangAnnotator sSingleton;
|
||||||
|
};
|
||||||
|
PendingInputEventHangAnnotator PendingInputEventHangAnnotator::sSingleton;
|
||||||
|
#endif
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
|
NS_IMPL_ISUPPORTS(BackgroundChildPrimer, nsIIPCBackgroundChildCreateCallback)
|
||||||
|
|
||||||
ContentChild* ContentChild::sSingleton;
|
ContentChild* ContentChild::sSingleton;
|
||||||
@@ -638,6 +661,10 @@ ContentChild::Init(MessageLoop* aIOLoop,
|
|||||||
|
|
||||||
SetProcessName(NS_LITERAL_STRING("Web Content"));
|
SetProcessName(NS_LITERAL_STRING("Web Content"));
|
||||||
|
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
HangMonitor::RegisterAnnotator(PendingInputEventHangAnnotator::sSingleton);
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2930,6 +2957,10 @@ ContentChild::RecvShutdown()
|
|||||||
|
|
||||||
mShuttingDown = true;
|
mShuttingDown = true;
|
||||||
|
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
HangMonitor::UnregisterAnnotator(PendingInputEventHangAnnotator::sSingleton);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (mPolicy) {
|
if (mPolicy) {
|
||||||
mPolicy->Deactivate();
|
mPolicy->Deactivate();
|
||||||
mPolicy = nullptr;
|
mPolicy = nullptr;
|
||||||
@@ -3580,6 +3611,33 @@ ContentChild::GetSpecificMessageEventTarget(const Message& aMsg)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
void
|
||||||
|
ContentChild::OnChannelReceivedMessage(const Message& aMsg)
|
||||||
|
{
|
||||||
|
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
||||||
|
mPendingInputEvents++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PContentChild::Result
|
||||||
|
ContentChild::OnMessageReceived(const Message& aMsg)
|
||||||
|
{
|
||||||
|
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
||||||
|
DebugOnly<uint32_t> prevEvts = mPendingInputEvents--;
|
||||||
|
MOZ_ASSERT(prevEvts > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PContentChild::OnMessageReceived(aMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
PContentChild::Result
|
||||||
|
ContentChild::OnMessageReceived(const Message& aMsg, Message*& aReply)
|
||||||
|
{
|
||||||
|
return PContentChild::OnMessageReceived(aMsg, aReply);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
||||||
#if !defined(XP_WIN)
|
#if !defined(XP_WIN)
|
||||||
|
|||||||
@@ -681,6 +681,17 @@ public:
|
|||||||
nsTArray<PluginTag>&& aPluginTags,
|
nsTArray<PluginTag>&& aPluginTags,
|
||||||
nsTArray<FakePluginTag>&& aFakePluginTags) override;
|
nsTArray<FakePluginTag>&& aFakePluginTags) override;
|
||||||
|
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
// Fetch the current number of pending input events.
|
||||||
|
//
|
||||||
|
// NOTE: This method performs an atomic read, and is safe to call from all threads.
|
||||||
|
uint32_t
|
||||||
|
GetPendingInputEvents()
|
||||||
|
{
|
||||||
|
return mPendingInputEvents;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
|
||||||
void StartForceKillTimer();
|
void StartForceKillTimer();
|
||||||
@@ -695,6 +706,17 @@ private:
|
|||||||
virtual already_AddRefed<nsIEventTarget>
|
virtual already_AddRefed<nsIEventTarget>
|
||||||
GetSpecificMessageEventTarget(const Message& aMsg) override;
|
GetSpecificMessageEventTarget(const Message& aMsg) override;
|
||||||
|
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
virtual void
|
||||||
|
OnChannelReceivedMessage(const Message& aMsg) override;
|
||||||
|
|
||||||
|
virtual PContentChild::Result
|
||||||
|
OnMessageReceived(const Message& aMsg) override;
|
||||||
|
|
||||||
|
virtual PContentChild::Result
|
||||||
|
OnMessageReceived(const Message& aMsg, Message*& aReply) override;
|
||||||
|
#endif
|
||||||
|
|
||||||
InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
|
InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
|
||||||
RefPtr<ConsoleListener> mConsoleListener;
|
RefPtr<ConsoleListener> mConsoleListener;
|
||||||
|
|
||||||
@@ -765,6 +787,11 @@ private:
|
|||||||
|
|
||||||
mozilla::Atomic<bool> mShuttingDown;
|
mozilla::Atomic<bool> mShuttingDown;
|
||||||
|
|
||||||
|
#ifdef NIGHTLY_BUILD
|
||||||
|
// NOTE: This member is atomic because it can be accessed from off-main-thread.
|
||||||
|
mozilla::Atomic<uint32_t> mPendingInputEvents;
|
||||||
|
#endif
|
||||||
|
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1404,23 +1404,9 @@ PuppetWidget::HasPendingInputEvent()
|
|||||||
|
|
||||||
mTabChild->GetIPCChannel()->PeekMessages(
|
mTabChild->GetIPCChannel()->PeekMessages(
|
||||||
[&ret](const IPC::Message& aMsg) -> bool {
|
[&ret](const IPC::Message& aMsg) -> bool {
|
||||||
if ((aMsg.type() & mozilla::dom::PBrowser::PBrowserStart)
|
if (nsContentUtils::IsMessageInputEvent(aMsg)) {
|
||||||
== mozilla::dom::PBrowser::PBrowserStart) {
|
ret = true;
|
||||||
switch (aMsg.type()) {
|
return false; // Stop peeking.
|
||||||
case mozilla::dom::PBrowser::Msg_RealMouseMoveEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_RealMouseButtonEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_RealKeyEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_MouseWheelEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_RealTouchEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_RealTouchMoveEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_RealDragEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_UpdateDimensions__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_MouseEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_KeyEvent__ID:
|
|
||||||
case mozilla::dom::PBrowser::Msg_SetDocShellIsActive__ID:
|
|
||||||
ret = true;
|
|
||||||
return false; // Stop peeking.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user