Chromium Code Reviews| Index: content/renderer/render_widget.cc |
| diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc |
| index 6b190b3883230f2741af65b02127141d943de3df..e417113b31cdf51876eef7214b596038d6a38358 100644 |
| --- a/content/renderer/render_widget.cc |
| +++ b/content/renderer/render_widget.cc |
| @@ -74,6 +74,7 @@ RenderWidget::RenderWidget(RenderThreadBase* render_thread, |
| has_focus_(false), |
| handling_input_event_(false), |
| closing_(false), |
| + is_swapped_out_(false), |
| input_method_is_active_(false), |
| text_input_type_(WebKit::WebTextInputTypeNone), |
| popup_type_(popup_type), |
| @@ -92,7 +93,9 @@ RenderWidget::~RenderWidget() { |
| RenderProcess::current()->ReleaseTransportDIB(current_paint_buf_); |
| current_paint_buf_ = NULL; |
| } |
| - RenderProcess::current()->ReleaseProcess(); |
| + // If we are swapped out, we have released already. |
| + if (!is_swapped_out_) |
| + RenderProcess::current()->ReleaseProcess(); |
| } |
| // static |
| @@ -160,6 +163,20 @@ void RenderWidget::CompleteInit(gfx::NativeViewId parent_hwnd, |
| Send(new ViewHostMsg_RenderViewReady(routing_id_)); |
| } |
| +void RenderWidget::SetSwappedOut(bool is_swapped_out) { |
| + // We should only toggle between states. |
| + DCHECK(is_swapped_out_ != is_swapped_out); |
| + is_swapped_out_ = is_swapped_out; |
| + |
| + // If we are swapping out, we will call ReleaseProcess, allowing the process |
| + // to exit if all of its RenderViews are swapped out. We wait until the |
| + // WasSwappedOut call to do this, to avoid showing the sad tab. |
| + // If we are swapping in, we call AddRefProcess to prevent the process from |
| + // exiting. |
| + if (!is_swapped_out) |
| + RenderProcess::current()->AddRefProcess(); |
| +} |
| + |
| bool RenderWidget::OnMessageReceived(const IPC::Message& message) { |
| bool handled = true; |
| IPC_BEGIN_MESSAGE_MAP(RenderWidget, message) |
| @@ -168,6 +185,7 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) { |
| IPC_MESSAGE_HANDLER(ViewMsg_Resize, OnResize) |
| IPC_MESSAGE_HANDLER(ViewMsg_WasHidden, OnWasHidden) |
| IPC_MESSAGE_HANDLER(ViewMsg_WasRestored, OnWasRestored) |
| + IPC_MESSAGE_HANDLER(ViewMsg_WasSwappedOut, OnWasSwappedOut) |
| IPC_MESSAGE_HANDLER(ViewMsg_UpdateRect_ACK, OnUpdateRectAck) |
| IPC_MESSAGE_HANDLER(ViewMsg_HandleInputEvent, OnHandleInputEvent) |
| IPC_MESSAGE_HANDLER(ViewMsg_MouseCaptureLost, OnMouseCaptureLost) |
| @@ -184,9 +202,25 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) { |
| return handled; |
| } |
| +bool RenderWidget::CanSendWhileSwappedOut(IPC::Message* message) { |
|
Matt Perry
2011/05/05 17:06:50
It's a shame that these message lists are duplicat
Charlie Reis
2011/05/10 20:15:09
The lists aren't identical, but it does seem like
Matt Perry
2011/05/10 20:26:32
Oh interesting. There are some messages that you w
Charlie Reis
2011/05/10 20:35:23
Yes-- there are several messages that the renderer
Charlie Reis
2011/05/10 23:17:56
Fixed in the new patch set. I abstract it out to
|
| + // We filter out most IPC messages when swapped out. However, some are |
| + // important (e.g., ACKs) for keeping the browser and renderer state |
| + // consistent in case we later return to this renderer. |
| + switch (message->type()) { |
| + case ViewHostMsg_HandleInputEvent_ACK::ID: |
| + case ViewHostMsg_PaintAtSize_ACK::ID: |
| + case ViewHostMsg_UpdateRect::ID: |
| + return true; |
| + default: |
| + break; |
| + } |
| + return false; |
| +} |
| + |
| bool RenderWidget::Send(IPC::Message* message) { |
| - // Don't send any messages after the browser has told us to close. |
| - if (closing_) { |
| + // Don't send any messages after the browser has told us to close, and filter |
| + // most outgoing messages while swapped out. |
| + if (closing_ || (is_swapped_out_ && !CanSendWhileSwappedOut(message))) { |
| delete message; |
| return false; |
| } |
| @@ -299,6 +333,14 @@ void RenderWidget::OnWasRestored(bool needs_repainting) { |
| } |
| } |
| +void RenderWidget::OnWasSwappedOut() { |
| + // If we have been swapped out and no one else is using this process, |
| + // it's safe to exit now. If we get swapped back in, we will call |
| + // AddRefProcess in SetSwappedOut. |
| + if (is_swapped_out_) |
| + RenderProcess::current()->ReleaseProcess(); |
| +} |
| + |
| void RenderWidget::OnRequestMoveAck() { |
| DCHECK(pending_window_rect_count_); |
| pending_window_rect_count_--; |