diff options
author | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-25 21:35:10 +0000 |
---|---|---|
committer | darin@chromium.org <darin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-25 21:35:10 +0000 |
commit | 7e2fa03804bef4bff9c5bb941f2edf09b6d234c0 (patch) | |
tree | 535d81a14867f7b037bec19764bfaa56a53acd33 /chrome | |
parent | 5f715e9411a0b4b8e207072fdbfad5160f5ad1e2 (diff) | |
download | chromium_src-7e2fa03804bef4bff9c5bb941f2edf09b6d234c0.zip chromium_src-7e2fa03804bef4bff9c5bb941f2edf09b6d234c0.tar.gz chromium_src-7e2fa03804bef4bff9c5bb941f2edf09b6d234c0.tar.bz2 |
Stop spamming delayed tasks on each input event.
R=mbelshe
BUG=2693
Review URL: http://codereview.chromium.org/4262
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2609 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/render_view_host.cc | 8 | ||||
-rw-r--r-- | chrome/browser/render_widget_host.cc | 43 | ||||
-rw-r--r-- | chrome/browser/render_widget_host.h | 31 |
3 files changed, 54 insertions, 28 deletions
diff --git a/chrome/browser/render_view_host.cc b/chrome/browser/render_view_host.cc index 8c95e07..27b25c9 100644 --- a/chrome/browser/render_view_host.cc +++ b/chrome/browser/render_view_host.cc @@ -233,7 +233,7 @@ void RenderViewHost::FirePageBeforeUnload() { // Start the hang monitor in case the renderer hangs in the beforeunload // handler. is_waiting_for_unload_ack_ = true; - StartHangMonitorTimeout(kUnloadTimeoutMS); + StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); Send(new ViewMsg_ShouldClose(routing_id_)); } else { // This RenderViewHost doesn't have a live renderer, so just skip running @@ -245,7 +245,7 @@ void RenderViewHost::FirePageBeforeUnload() { void RenderViewHost::FirePageUnload() { // Start the hang monitor in case the renderer hangs in the unload handler. is_waiting_for_unload_ack_ = true; - StartHangMonitorTimeout(kUnloadTimeoutMS); + StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); ClosePage(site_instance()->process_host_id(), routing_id()); } @@ -487,7 +487,7 @@ void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg, bool success, const std::wstring& prompt) { if (is_waiting_for_unload_ack_) - StartHangMonitorTimeout(kUnloadTimeoutMS); + StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); if (--modal_dialog_count_ == 0) ResetEvent(modal_dialog_event_.Get()); @@ -498,7 +498,7 @@ void RenderViewHost::JavaScriptMessageBoxClosed(IPC::Message* reply_msg, void RenderViewHost::ModalHTMLDialogClosed(IPC::Message* reply_msg, const std::string& json_retval) { if (is_waiting_for_unload_ack_) - StartHangMonitorTimeout(kUnloadTimeoutMS); + StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kUnloadTimeoutMS)); if (--modal_dialog_count_ == 0) ResetEvent(modal_dialog_event_.Get()); diff --git a/chrome/browser/render_widget_host.cc b/chrome/browser/render_widget_host.cc index 34e9c26..449b194 100644 --- a/chrome/browser/render_widget_host.cc +++ b/chrome/browser/render_widget_host.cc @@ -273,7 +273,6 @@ RenderWidgetHost::RenderWidgetHost(RenderProcessHost* process, int routing_id) is_hidden_(false), suppress_view_updating_(false), needs_repainting_on_restore_(false), - hung_renderer_factory_(this), is_unresponsive_(false), view_being_painted_(false), repaint_ack_pending_(false) { @@ -630,7 +629,7 @@ void RenderWidgetHost::ForwardInputEvent(const WebInputEvent& input_event, // any input event cancels a pending mouse move event next_mouse_move_.reset(); - StartHangMonitorTimeout(kHungRendererDelayMs); + StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); } void RenderWidgetHost::Shutdown() { @@ -673,7 +672,19 @@ void RenderWidgetHost::Destroy() { delete this; } -void RenderWidgetHost::RendererIsUnresponsive() { +void RenderWidgetHost::CheckRendererIsUnresponsive() { + // If we received a call to StopHangMonitorTimeout. + if (time_when_considered_hung_.is_null()) + return; + + // If we have not waited long enough, then wait some more. + Time now = Time::Now(); + if (now < time_when_considered_hung_) { + StartHangMonitorTimeout(time_when_considered_hung_ - now); + return; + } + + // OK, looks like we have a hung renderer! NotificationService::current()->Notify(NOTIFY_RENDERER_PROCESS_HANG, Source<RenderWidgetHost>(this), NotificationService::NoDetails()); @@ -788,19 +799,31 @@ void RenderWidgetHost::ScrollRect(HANDLE bitmap, const gfx::Rect& bitmap_rect, } void RenderWidgetHost::RestartHangMonitorTimeout() { - hung_renderer_factory_.RevokeAll(); - StartHangMonitorTimeout(kHungRendererDelayMs); + StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); } void RenderWidgetHost::StopHangMonitorTimeout() { - hung_renderer_factory_.RevokeAll(); + time_when_considered_hung_ = Time(); RendererIsResponsive(); + + // We do not bother to stop the hung_renderer_timer_ here in case it will be + // started again shortly, which happens to be the common use case. } -void RenderWidgetHost::StartHangMonitorTimeout(int delay) { - MessageLoop::current()->PostDelayedTask(FROM_HERE, - hung_renderer_factory_.NewRunnableMethod( - &RenderWidgetHost::RendererIsUnresponsive), delay); +void RenderWidgetHost::StartHangMonitorTimeout(TimeDelta delay) { + time_when_considered_hung_ = Time::Now() + delay; + + // If we already have a timer that will expire at or before the given delay, + // then we have nothing more to do now. + if (hung_renderer_timer_.IsRunning() && + hung_renderer_timer_.GetCurrentDelay() <= delay) + return; + + // Either the timer is not yet running, or we need to adjust the timer to + // fire sooner. + hung_renderer_timer_.Stop(); + hung_renderer_timer_.Start(delay, this, + &RenderWidgetHost::CheckRendererIsUnresponsive); } void RenderWidgetHost::RendererExited() { diff --git a/chrome/browser/render_widget_host.h b/chrome/browser/render_widget_host.h index 0db4dbd..fd542e7 100644 --- a/chrome/browser/render_widget_host.h +++ b/chrome/browser/render_widget_host.h @@ -2,13 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_RENDER_WIDGET_HOST_H__ -#define CHROME_BROWSER_RENDER_WIDGET_HOST_H__ +#ifndef CHROME_BROWSER_RENDER_WIDGET_HOST_H_ +#define CHROME_BROWSER_RENDER_WIDGET_HOST_H_ #include <windows.h> -#include "base/task.h" #include "base/gfx/size.h" +#include "base/timer.h" #include "chrome/common/ipc_channel.h" namespace gfx { @@ -180,11 +180,11 @@ class RenderWidgetHost : public IPC::Channel::Listener { // javascript call. virtual bool CanBlur() const { return true; } - // Restart the active hang monitor timeout. Clears all existing timeouts - // and starts with a new one. - // This can be because the renderer has become active, the tab is being - // hidden, or the user has chosen to wait some more to give the tab a chance - // to become active and we don't want to display a warning too soon. + // Restart the active hang monitor timeout. Clears all existing timeouts and + // starts with a new one. This can be because the renderer has become + // active, the tab is being hidden, or the user has chosen to wait some more + // to give the tab a chance to become active and we don't want to display a + // warning too soon. void RestartHangMonitorTimeout(); // Stops all existing hang monitor timeouts and assumes the renderer is @@ -194,7 +194,7 @@ class RenderWidgetHost : public IPC::Channel::Listener { // Starts a hang monitor timeout. If there's already a hang monitor timeout // the new one will only fire if it has a shorter delay than the time // left on the existing timeouts. - void StartHangMonitorTimeout(int delay); + void StartHangMonitorTimeout(TimeDelta delay); // Called when we receive a notification indicating that the renderer // process has gone. @@ -250,7 +250,7 @@ class RenderWidgetHost : public IPC::Channel::Listener { // Callbacks for notification when the renderer becomes unresponsive to user // input events, and subsequently responsive again. The delegate can use // these notifications to show a warning. - void RendererIsUnresponsive(); + void CheckRendererIsUnresponsive(); virtual void NotifyRendererUnresponsive() {} void RendererIsResponsive(); virtual void NotifyRendererResponsive() {} @@ -298,8 +298,12 @@ class RenderWidgetHost : public IPC::Channel::Listener { // itself, a paint message could already be in flight at that point. bool needs_repainting_on_restore_; - // The following factory is used to detect a hung renderer - ScopedRunnableMethodFactory<RenderWidgetHost> hung_renderer_factory_; + // The following value indicates a time in the future when we would consider + // the renderer hung if it does not generate an appropriate response message. + Time time_when_considered_hung_; + + // This timer runs to check if time_when_considered_hung_ has past. + base::OneShotTimer<RenderWidgetHost> hung_renderer_timer_; // This is true if the renderer is currently unresponsive. bool is_unresponsive_; @@ -359,5 +363,4 @@ class RenderWidgetHost::PaintObserver { virtual void RenderWidgetHostDidPaint(RenderWidgetHost* rwh) = 0; }; -#endif // #ifndef CHROME_BROWSER_RENDER_WIDGET_HOST_H__ - +#endif // #ifndef CHROME_BROWSER_RENDER_WIDGET_HOST_H_ |