summaryrefslogtreecommitdiffstats
path: root/chrome/browser/renderer_host
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-25 01:15:11 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-25 01:15:11 +0000
commit829e761119a8b9380d072aac47cdf5b81a5db2b5 (patch)
tree2ff55d2d651691a58efecd0681f6798e75108321 /chrome/browser/renderer_host
parentcdddc17b8e74ddeac3621a4016c8dcbb453b8365 (diff)
downloadchromium_src-829e761119a8b9380d072aac47cdf5b81a5db2b5.zip
chromium_src-829e761119a8b9380d072aac47cdf5b81a5db2b5.tar.gz
chromium_src-829e761119a8b9380d072aac47cdf5b81a5db2b5.tar.bz2
Fix sudden termination after the latest WebKit merge.
BUG=10927 Review URL: http://codereview.chromium.org/93104 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14517 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/renderer_host')
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc24
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.h10
-rw-r--r--chrome/browser/renderer_host/render_process_host.cc3
-rw-r--r--chrome/browser/renderer_host/render_process_host.h15
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc19
-rw-r--r--chrome/browser/renderer_host/render_view_host.h19
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h4
7 files changed, 49 insertions, 45 deletions
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index a75d9de..824f5a9 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -480,7 +480,16 @@ bool BrowserRenderProcessHost::FastShutdownIfPossible() {
if (BrowserRenderProcessHost::run_renderer_in_process())
return false; // Since process mode can't do fast shutdown.
- // Test if there's an unload listener
+ // Test if there's an unload listener.
+ // NOTE: It's possible that an onunload listener may be installed
+ // while we're shutting down, so there's a small race here. Given that
+ // the window is small, it's unlikely that the web page has much
+ // state that will be lost by not calling its unload handlers properly.
+ if (!sudden_termination_allowed())
+ return false;
+
+ // Check for any external tab containers, since they may still be running even
+ // though this window closed.
BrowserRenderProcessHost::listeners_iterator iter;
// NOTE: This is a bit dangerous. We know that for now, listeners are
// always RenderWidgetHosts. But in theory, they don't have to be.
@@ -490,13 +499,8 @@ bool BrowserRenderProcessHost::FastShutdownIfPossible() {
if (!widget || !widget->IsRenderView())
continue;
RenderViewHost* rvh = static_cast<RenderViewHost*>(widget);
- if (!rvh->CanTerminate()) {
- // NOTE: It's possible that an onunload listener may be installed
- // while we're shutting down, so there's a small race here. Given that
- // the window is small, it's unlikely that the web page has much
- // state that will be lost by not calling its unload handlers properly.
+ if (rvh->delegate()->IsExternalTabContainer())
return false;
- }
}
// Otherwise, we're allowed to just terminate the process. Using exit code 0
@@ -582,6 +586,8 @@ void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdatedCacheStats,
OnUpdatedCacheStats)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged,
+ SuddenTerminationChanged);
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP_EX()
@@ -702,6 +708,10 @@ void BrowserRenderProcessHost::OnUpdatedCacheStats(
WebCacheManager::GetInstance()->ObserveStats(pid(), stats);
}
+void BrowserRenderProcessHost::SuddenTerminationChanged(bool enabled) {
+ set_sudden_termination_allowed(enabled);
+}
+
void BrowserRenderProcessHost::SetBackgrounded(bool backgrounded) {
// If the process_ is NULL, the process hasn't been created yet.
if (process_.handle()) {
diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h
index c6517b8..1914432 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.h
+++ b/chrome/browser/renderer_host/browser_render_process_host.h
@@ -90,16 +90,8 @@ class BrowserRenderProcessHost : public RenderProcessHost,
// Control message handlers.
void OnPageContents(const GURL& url, int32 page_id,
const std::wstring& contents);
- // Clipboard messages
- void OnClipboardWriteHTML(const std::wstring& markup, const GURL& src_url);
- void OnClipboardWriteBookmark(const std::wstring& title, const GURL& url);
- void OnClipboardWriteBitmap(base::SharedMemoryHandle bitmap, gfx::Size size);
- void OnClipboardIsFormatAvailable(unsigned int format, bool* result);
- void OnClipboardReadText(string16* result);
- void OnClipboardReadAsciiText(std::string* result);
- void OnClipboardReadHTML(string16* markup, GURL* src_url);
-
void OnUpdatedCacheStats(const WebKit::WebCache::UsageStats& stats);
+ void SuddenTerminationChanged(bool enabled);
// Initialize support for visited links. Send the renderer process its initial
// set of visited links.
diff --git a/chrome/browser/renderer_host/render_process_host.cc b/chrome/browser/renderer_host/render_process_host.cc
index 0fdde82..e70596743 100644
--- a/chrome/browser/renderer_host/render_process_host.cc
+++ b/chrome/browser/renderer_host/render_process_host.cc
@@ -66,7 +66,8 @@ bool RenderProcessHost::run_renderer_in_process_ = false;
RenderProcessHost::RenderProcessHost(Profile* profile)
: max_page_id_(-1),
pid_(-1),
- profile_(profile) {
+ profile_(profile),
+ sudden_termination_allowed_(true) {
}
RenderProcessHost::~RenderProcessHost() {
diff --git a/chrome/browser/renderer_host/render_process_host.h b/chrome/browser/renderer_host/render_process_host.h
index f972d39..0347427 100644
--- a/chrome/browser/renderer_host/render_process_host.h
+++ b/chrome/browser/renderer_host/render_process_host.h
@@ -46,6 +46,13 @@ class RenderProcessHost : public IPC::Channel::Sender,
// May return NULL if there is no connection.
IPC::SyncChannel* channel() { return channel_.get(); }
+ bool sudden_termination_allowed() const {
+ return sudden_termination_allowed_;
+ }
+ void set_sudden_termination_allowed(bool enabled) {
+ sudden_termination_allowed_ = enabled;
+ }
+
// Used for refcounting, each holder of this object must Attach and Release
// just like it would for a COM object. This object should be allocated on
// the heap; when no listeners own it any more, it will delete itself.
@@ -196,6 +203,14 @@ class RenderProcessHost : public IPC::Channel::Sender,
// set of listeners that expect the renderer process to close
std::set<int> listeners_expecting_close_;
+ // True if the process can be shut down suddenly. If this is true, then we're
+ // sure that all the RenderViews in the process can be shutdown suddenly. If
+ // it's false, then specific RenderViews might still be allowed to be shutdown
+ // suddenly by checking their SuddenTerminationAllowed() flag. This can occur
+ // if one tab has an unload event listener but another tab in the same process
+ // doesn't.
+ bool sudden_termination_allowed_;
+
// See getter above.
static bool run_renderer_in_process_;
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 73d888d6..21b8d34 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -100,9 +100,9 @@ RenderViewHost::RenderViewHost(SiteInstance* instance,
navigations_suspended_(false),
suspended_nav_message_(NULL),
run_modal_reply_msg_(NULL),
- has_unload_listener_(false),
is_waiting_for_unload_ack_(false),
- are_javascript_messages_suppressed_(false) {
+ are_javascript_messages_suppressed_(false),
+ sudden_termination_allowed_(false) {
DCHECK(instance_);
DCHECK(delegate_);
if (modal_dialog_event == NULL)
@@ -285,7 +285,7 @@ void RenderViewHost::ClosePageIgnoringUnloadEvents(int render_process_host_id,
rvh->StopHangMonitorTimeout();
rvh->is_waiting_for_unload_ack_ = false;
- rvh->UnloadListenerHasFired();
+ rvh->set_sudden_termination_allowed(true);
rvh->delegate()->Close(rvh);
}
@@ -658,11 +658,8 @@ void RenderViewHost::LoadStateChanged(const GURL& url,
delegate_->LoadStateChanged(url, load_state);
}
-bool RenderViewHost::CanTerminate() const {
- if (!delegate_->CanTerminate())
- return false;
-
- return !has_unload_listener_;
+bool RenderViewHost::SuddenTerminationAllowed() const {
+ return sudden_termination_allowed_ || process()->sudden_termination_allowed();
}
///////////////////////////////////////////////////////////////////////////////
@@ -761,8 +758,6 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_FORWARD(ViewHostMsg_JSOutOfMemory, delegate_,
RenderViewHostDelegate::OnJSOutOfMemory);
IPC_MESSAGE_HANDLER(ViewHostMsg_ShouldClose_ACK, OnMsgShouldCloseACK);
- IPC_MESSAGE_HANDLER(ViewHostMsg_UnloadListenerChanged,
- OnUnloadListenerChanged);
IPC_MESSAGE_HANDLER(ViewHostMsg_QueryFormFieldAutofill,
OnQueryFormFieldAutofill)
IPC_MESSAGE_HANDLER(ViewHostMsg_RemoveAutofillEntry,
@@ -1298,10 +1293,6 @@ void RenderViewHost::OnMsgShouldCloseACK(bool proceed) {
delegate_->ShouldClosePage(proceed);
}
-void RenderViewHost::OnUnloadListenerChanged(bool has_listener) {
- has_unload_listener_ = has_listener;
-}
-
void RenderViewHost::OnQueryFormFieldAutofill(const std::wstring& field_name,
const std::wstring& user_text,
int64 node_id,
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 635f587..f15131c 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -377,15 +377,10 @@ class RenderViewHost : public RenderWidgetHost {
// Notifies the RenderViewHost that its load state changed.
void LoadStateChanged(const GURL& url, net::LoadState load_state);
- // Does the associated view have an onunload or onbeforeunload handler?
- bool HasUnloadListener() { return has_unload_listener_; }
-
- // If the associated view can be terminated without any side effects
- bool CanTerminate() const;
-
- // Clears the has_unload_listener_ bit since the unload handler has fired
- // and we're necessarily leaving the page.
- void UnloadListenerHasFired() { has_unload_listener_ = false; }
+ bool SuddenTerminationAllowed() const;
+ void set_sudden_termination_allowed(bool enabled) {
+ sudden_termination_allowed_ = enabled;
+ }
// Forward a message from external host to chrome renderer.
void ForwardMessageFromExternalHost(const std::string& message,
@@ -539,7 +534,6 @@ class RenderViewHost : public RenderWidgetHost {
void OnDidGetApplicationInfo(int32 page_id,
const webkit_glue::WebApplicationInfo& info);
void OnMsgShouldCloseACK(bool proceed);
- void OnUnloadListenerChanged(bool has_handler);
void OnQueryFormFieldAutofill(const std::wstring& field_name,
const std::wstring& user_text,
int64 node_id,
@@ -613,8 +607,6 @@ class RenderViewHost : public RenderWidgetHost {
// must return to the renderer to unblock it.
IPC::Message* run_modal_reply_msg_;
- bool has_unload_listener_;
-
bool is_waiting_for_unload_ack_;
bool are_javascript_messages_suppressed_;
@@ -622,6 +614,9 @@ class RenderViewHost : public RenderWidgetHost {
// Handles processing IPC messages request extension functions be executed.
scoped_ptr<ExtensionFunctionDispatcher> extension_function_dispatcher_;
+ // True if the render view can be shut down suddenly.
+ bool sudden_termination_allowed_;
+
DISALLOW_COPY_AND_ASSIGN(RenderViewHost);
};
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index ebe8df1..ba69b03 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -416,8 +416,8 @@ class RenderViewHostDelegate {
// bombing), see DownloadRequestManager for details.
virtual void OnEnterOrSpace() { }
- // If this view can be terminated without any side effects
- virtual bool CanTerminate() const { return true; }
+ // If this view is used to host an external tab container.
+ virtual bool IsExternalTabContainer() const { return false; }
// A find operation in the current page completed.
virtual void OnFindReply(int request_id,