diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-05 02:07:18 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-05 02:07:18 +0000 |
commit | 20b64d30cee31ae12e29a520836d25e93a192c6d (patch) | |
tree | 81815977aefce88c281c54dfcf750f418d0cb99b /chrome/browser/plugin_process_host.cc | |
parent | df813ac7b79f6c935df34dc82d8d6018d0a3d032 (diff) | |
download | chromium_src-20b64d30cee31ae12e29a520836d25e93a192c6d.zip chromium_src-20b64d30cee31ae12e29a520836d25e93a192c6d.tar.gz chromium_src-20b64d30cee31ae12e29a520836d25e93a192c6d.tar.bz2 |
Ensure that we display a sad face for a windowed plugin when the plugin process crashes. This was a regression introduced by creating the plugin parent on the browser UI thread, which remains valid when the plugin process crashes.
The fix is to track plugin wrapper windows in the PluginProcessHost class and destroy any remaining windows in the destructor. Removed the DestroyWindowTask
which destroys the windows on the UI thread. We can achieve the same result by posting WM_CLOSE messages to these windows.
This fixes http://code.google.com/p/chromium/issues/detail?id=7673
Bug=7673
Review URL: http://codereview.chromium.org/40120
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10960 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/plugin_process_host.cc')
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc index 3ce2a74..6221ada 100644 --- a/chrome/browser/plugin_process_host.cc +++ b/chrome/browser/plugin_process_host.cc @@ -269,11 +269,14 @@ void PluginDownloadUrlHelper::DownloadCompletedHelper(bool success) { delete this; } +#if defined(OS_WIN) // Sends the reply to the create window message on the IO thread. class SendReplyTask : public Task { public: - SendReplyTask(FilePath plugin_path, IPC::Message* reply_msg) - : plugin_path_(plugin_path), reply_msg_(reply_msg) { } + SendReplyTask(FilePath plugin_path, HWND window, IPC::Message* reply_msg) + : plugin_path_(plugin_path), + reply_msg_(reply_msg), + window_(window){ } virtual void Run() { PluginProcessHost* plugin = @@ -281,16 +284,16 @@ class SendReplyTask : public Task { if (!plugin) return; + plugin->AddWindow(window_); plugin->Send(reply_msg_); } private: FilePath plugin_path_; IPC::Message* reply_msg_; + HWND window_; }; -#if defined(OS_WIN) - // Creates a child window of the given HWND on the UI thread. class CreateWindowTask : public Task { public: @@ -328,7 +331,7 @@ class CreateWindowTask : public Task { reply_msg_, window); g_browser_process->io_thread()->message_loop()->PostTask( - FROM_HERE, new SendReplyTask(plugin_path_, reply_msg_)); + FROM_HERE, new SendReplyTask(plugin_path_, window, reply_msg_)); } private: @@ -337,20 +340,6 @@ class CreateWindowTask : public Task { IPC::Message* reply_msg_; }; -// Destroys the given window on the UI thread. -class DestroyWindowTask : public Task { - public: - explicit DestroyWindowTask(HWND window) : window_(window) { } - - virtual void Run() { - DestroyWindow(window_); - TRACK_HWND_DESTRUCTION(window_); - } - - private: - HWND window_; -}; - void PluginProcessHost::OnCreateWindow(HWND parent, IPC::Message* reply_msg) { // Need to create this window on the UI thread. @@ -359,8 +348,17 @@ void PluginProcessHost::OnCreateWindow(HWND parent, } void PluginProcessHost::OnDestroyWindow(HWND window) { - PluginService::GetInstance()->main_message_loop()->PostTask( - FROM_HERE, new DestroyWindowTask(window)); + std::set<HWND>::iterator window_index = + plugin_parent_windows_set_.find(window); + if (window_index != plugin_parent_windows_set_.end()) { + plugin_parent_windows_set_.erase(window_index); + } + + PostMessage(window, WM_CLOSE, 0, 0); +} + +void PluginProcessHost::AddWindow(HWND window) { + plugin_parent_windows_set_.insert(window); } #endif // defined(OS_WIN) @@ -376,6 +374,21 @@ PluginProcessHost::~PluginProcessHost() { // fixed. PluginService::GetInstance()->resource_dispatcher_host()-> CancelRequestsForProcess(-1); + +#if defined(OS_WIN) + // We erase HWNDs from the plugin_parent_windows_set_ when we receive a + // notification that the window is being destroyed. If we don't receive this + // notification and the PluginProcessHost instance is being destroyed, it + // means that the plugin process crashed. We paint a sad face in this case in + // the renderer process. To ensure that the sad face shows up, and we don't + // leak HWNDs, we should destroy existing plugin parent windows. + std::set<HWND>::iterator window_index; + for (window_index = plugin_parent_windows_set_.begin(); + window_index != plugin_parent_windows_set_.end(); + window_index++) { + PostMessage(*window_index, WM_CLOSE, 0, 0); + } +#endif } bool PluginProcessHost::Init(const WebPluginInfo& info, |