diff options
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 55 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 11 |
2 files changed, 45 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, diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h index b9a5681..ead8c81 100644 --- a/chrome/browser/plugin_process_host.h +++ b/chrome/browser/plugin_process_host.h @@ -7,6 +7,7 @@ #include "build/build_config.h" +#include <set> #include <vector> #include "base/basictypes.h" @@ -79,6 +80,11 @@ class PluginProcessHost : public ChildProcessHost, const WebPluginInfo& info() const { return info_; } +#if defined(OS_WIN) + // Tracks plugin parent windows created on the browser UI thread. + void AddWindow(HWND window); +#endif + private: friend class PluginResolveProxyHelper; @@ -137,6 +143,11 @@ class PluginProcessHost : public ChildProcessHost, // the requests to the proxy service). ResolveProxyMsgHelper resolve_proxy_msg_helper_; +#if defined(OS_WIN) + // Tracks plugin parent windows created on the UI thread. + std::set<HWND> plugin_parent_windows_set_; +#endif + DISALLOW_EVIL_CONSTRUCTORS(PluginProcessHost); }; |