Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/renderer_host/render_widget_host.h" | 5 #include "content/browser/renderer_host/render_widget_host.h" |
| 6 | 6 |
| 7 #include "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 87 is_hidden_(false), | 87 is_hidden_(false), |
| 88 is_accelerated_compositing_active_(false), | 88 is_accelerated_compositing_active_(false), |
| 89 repaint_ack_pending_(false), | 89 repaint_ack_pending_(false), |
| 90 resize_ack_pending_(false), | 90 resize_ack_pending_(false), |
| 91 mouse_move_pending_(false), | 91 mouse_move_pending_(false), |
| 92 mouse_wheel_pending_(false), | 92 mouse_wheel_pending_(false), |
| 93 touch_move_pending_(false), | 93 touch_move_pending_(false), |
| 94 touch_event_is_queued_(false), | 94 touch_event_is_queued_(false), |
| 95 needs_repainting_on_restore_(false), | 95 needs_repainting_on_restore_(false), |
| 96 is_unresponsive_(false), | 96 is_unresponsive_(false), |
| 97 is_monitoring_for_hung_renderer_(false), | |
| 97 in_get_backing_store_(false), | 98 in_get_backing_store_(false), |
| 98 view_being_painted_(false), | 99 view_being_painted_(false), |
| 99 ignore_input_events_(false), | 100 ignore_input_events_(false), |
| 100 text_direction_updated_(false), | 101 text_direction_updated_(false), |
| 101 text_direction_(WebKit::WebTextDirectionLeftToRight), | 102 text_direction_(WebKit::WebTextDirectionLeftToRight), |
| 102 text_direction_canceled_(false), | 103 text_direction_canceled_(false), |
| 103 suppress_next_char_events_(false), | 104 suppress_next_char_events_(false), |
| 104 pending_mouse_lock_request_(false), | 105 pending_mouse_lock_request_(false), |
| 105 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | 106 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { |
| 106 if (routing_id_ == MSG_ROUTING_NONE) | 107 if (routing_id_ == MSG_ROUTING_NONE) |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 499 Send(new ViewMsg_Repaint(routing_id_, current_size_)); | 500 Send(new ViewMsg_Repaint(routing_id_, current_size_)); |
| 500 } | 501 } |
| 501 } | 502 } |
| 502 | 503 |
| 503 void RenderWidgetHost::StartHangMonitorTimeout(TimeDelta delay) { | 504 void RenderWidgetHost::StartHangMonitorTimeout(TimeDelta delay) { |
| 504 if (CommandLine::ForCurrentProcess()->HasSwitch( | 505 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 505 switches::kDisableHangMonitor)) { | 506 switches::kDisableHangMonitor)) { |
| 506 return; | 507 return; |
| 507 } | 508 } |
| 508 | 509 |
| 509 // If we already have a timer that will expire at or before the given delay, | 510 is_monitoring_for_hung_renderer_ = true; |
| 510 // then we have nothing more to do now. If we have set our end time to null | 511 |
| 511 // by calling StopHangMonitorTimeout, though, we will need to restart the | 512 // Start the timer if it's not already pending. |
| 512 // timer. | 513 if (!hung_renderer_timer_.IsRunning()) { |
| 513 if (hung_renderer_timer_.IsRunning() && | 514 hung_renderer_timer_.Start(FROM_HERE, delay, this, |
| 514 hung_renderer_timer_.GetCurrentDelay() <= delay && | 515 &RenderWidgetHost::CheckRendererIsUnresponsive); |
|
jbates
2011/11/10 01:51:31
This code seems to assume that GetCurrentDelay is
Charlie Reis
2011/11/10 19:35:54
Thanks for catching this!
| |
| 515 !time_when_considered_hung_.is_null()) { | |
| 516 return; | |
| 517 } | 516 } |
| 518 | |
| 519 // Either the timer is not yet running, or we need to adjust the timer to | |
| 520 // fire sooner. | |
| 521 time_when_considered_hung_ = Time::Now() + delay; | |
| 522 hung_renderer_timer_.Stop(); | |
| 523 hung_renderer_timer_.Start(FROM_HERE, delay, this, | |
| 524 &RenderWidgetHost::CheckRendererIsUnresponsive); | |
| 525 } | 517 } |
| 526 | 518 |
| 527 void RenderWidgetHost::RestartHangMonitorTimeout() { | 519 void RenderWidgetHost::RestartHangMonitorTimeout() { |
| 528 // Setting to null will cause StartHangMonitorTimeout to restart the timer. | 520 time_of_last_renderer_response_ = TimeTicks::Now(); |
|
jbates
2011/11/10 01:51:31
Storing the time_of_last_renderer_response_ rather
Charlie Reis
2011/11/10 19:35:54
I like simplifying it, but I'm not sure this is co
| |
| 529 time_when_considered_hung_ = Time(); | |
|
jbates
2011/11/10 01:51:31
Instead of overloading the meaning of this time, I
Charlie Reis
2011/11/10 19:35:54
I like it.
| |
| 530 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); | 521 StartHangMonitorTimeout(TimeDelta::FromMilliseconds(kHungRendererDelayMs)); |
| 531 } | 522 } |
| 532 | 523 |
| 533 void RenderWidgetHost::StopHangMonitorTimeout() { | 524 void RenderWidgetHost::StopHangMonitorTimeout() { |
| 534 time_when_considered_hung_ = Time(); | 525 is_monitoring_for_hung_renderer_ = false; |
| 535 RendererIsResponsive(); | 526 RendererIsResponsive(); |
| 536 | 527 |
| 537 // We do not bother to stop the hung_renderer_timer_ here in case it will be | 528 // We do not bother to stop the hung_renderer_timer_ here in case it will be |
| 538 // started again shortly, which happens to be the common use case. | 529 // started again shortly, which happens to be the common use case. |
| 539 } | 530 } |
| 540 | 531 |
| 541 void RenderWidgetHost::ForwardMouseEvent(const WebMouseEvent& mouse_event) { | 532 void RenderWidgetHost::ForwardMouseEvent(const WebMouseEvent& mouse_event) { |
| 542 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardMouseEvent"); | 533 TRACE_EVENT0("renderer_host", "RenderWidgetHost::ForwardMouseEvent"); |
| 543 if (ignore_input_events_ || process_->ignore_input_events()) | 534 if (ignore_input_events_ || process_->ignore_input_events()) |
| 544 return; | 535 return; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 // of other messages on us. So if you do any other deinitialization here, | 843 // of other messages on us. So if you do any other deinitialization here, |
| 853 // do it after this call to view_->Destroy(). | 844 // do it after this call to view_->Destroy(). |
| 854 if (view_) | 845 if (view_) |
| 855 view_->Destroy(); | 846 view_->Destroy(); |
| 856 | 847 |
| 857 delete this; | 848 delete this; |
| 858 } | 849 } |
| 859 | 850 |
| 860 void RenderWidgetHost::CheckRendererIsUnresponsive() { | 851 void RenderWidgetHost::CheckRendererIsUnresponsive() { |
| 861 // If we received a call to StopHangMonitorTimeout. | 852 // If we received a call to StopHangMonitorTimeout. |
| 862 if (time_when_considered_hung_.is_null()) | 853 if (!is_monitoring_for_hung_renderer_) |
| 863 return; | 854 return; |
| 864 | 855 |
| 865 // If we have not waited long enough, then wait some more. | 856 // If we have not waited long enough, then wait some more. |
| 866 Time now = Time::Now(); | 857 TimeDelta elapsed_time = TimeTicks::Now() - time_of_last_renderer_response_; |
| 867 if (now < time_when_considered_hung_) { | 858 TimeDelta hung_delay = TimeDelta::FromMilliseconds(kHungRendererDelayMs); |
|
Charlie Reis
2011/11/10 19:35:54
This isn't correct-- we use different values in di
| |
| 868 StartHangMonitorTimeout(time_when_considered_hung_ - now); | 859 if (elapsed_time < hung_delay) { |
| 860 StartHangMonitorTimeout(hung_delay - elapsed_time); | |
| 869 return; | 861 return; |
| 870 } | 862 } |
| 871 | 863 |
| 872 // OK, looks like we have a hung renderer! | 864 // OK, looks like we have a hung renderer! |
| 873 content::NotificationService::current()->Notify( | 865 content::NotificationService::current()->Notify( |
| 874 content::NOTIFICATION_RENDERER_PROCESS_HANG, | 866 content::NOTIFICATION_RENDERER_PROCESS_HANG, |
| 875 content::Source<RenderWidgetHost>(this), | 867 content::Source<RenderWidgetHost>(this), |
| 876 content::NotificationService::NoDetails()); | 868 content::NotificationService::NoDetails()); |
| 877 is_unresponsive_ = true; | 869 is_unresponsive_ = true; |
| 878 NotifyRendererUnresponsive(); | 870 NotifyRendererUnresponsive(); |
| 879 } | 871 } |
| 880 | 872 |
| 881 void RenderWidgetHost::RendererIsResponsive() { | 873 void RenderWidgetHost::RendererIsResponsive() { |
| 874 time_of_last_renderer_response_ = TimeTicks::Now(); | |
| 882 if (is_unresponsive_) { | 875 if (is_unresponsive_) { |
| 883 is_unresponsive_ = false; | 876 is_unresponsive_ = false; |
| 884 NotifyRendererResponsive(); | 877 NotifyRendererResponsive(); |
| 885 } | 878 } |
| 886 } | 879 } |
| 887 | 880 |
| 888 void RenderWidgetHost::OnMsgRenderViewReady() { | 881 void RenderWidgetHost::OnMsgRenderViewReady() { |
| 889 WasResized(); | 882 WasResized(); |
| 890 } | 883 } |
| 891 | 884 |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1462 pending_mouse_lock_request_ = false; | 1455 pending_mouse_lock_request_ = false; |
| 1463 if (!view_ || !view_->HasFocus()|| !view_->LockMouse()) { | 1456 if (!view_ || !view_->HasFocus()|| !view_->LockMouse()) { |
| 1464 Send(new ViewMsg_LockMouse_ACK(routing_id_, false)); | 1457 Send(new ViewMsg_LockMouse_ACK(routing_id_, false)); |
| 1465 return false; | 1458 return false; |
| 1466 } else { | 1459 } else { |
| 1467 Send(new ViewMsg_LockMouse_ACK(routing_id_, true)); | 1460 Send(new ViewMsg_LockMouse_ACK(routing_id_, true)); |
| 1468 return true; | 1461 return true; |
| 1469 } | 1462 } |
| 1470 } | 1463 } |
| 1471 } | 1464 } |
| OLD | NEW |