| Index: content/renderer/render_widget.cc
|
| diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
|
| index 2597ad621ae524f5415bca80279b58061911565a..7572b7ed824ad6023fbbc08f6a0338cb9d508e66 100644
|
| --- a/content/renderer/render_widget.cc
|
| +++ b/content/renderer/render_widget.cc
|
| @@ -12,6 +12,7 @@
|
| #include "base/metrics/histogram.h"
|
| #include "build/build_config.h"
|
| #include "content/common/content_switches.h"
|
| +#include "content/common/swapped_out_messages.h"
|
| #include "content/common/view_messages.h"
|
| #include "content/renderer/render_process.h"
|
| #include "content/renderer/render_thread.h"
|
| @@ -74,6 +75,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 +94,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 +164,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 +186,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)
|
| @@ -185,8 +204,11 @@ bool RenderWidget::OnMessageReceived(const IPC::Message& message) {
|
| }
|
|
|
| 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 ((is_swapped_out_ &&
|
| + !content::SwappedOutMessages::CanSendWhileSwappedOut(message)) ||
|
| + closing_) {
|
| delete message;
|
| return false;
|
| }
|
| @@ -299,6 +321,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_--;
|
|
|