Index: chrome/browser/plugin_process_host.cc |
=================================================================== |
--- chrome/browser/plugin_process_host.cc (revision 10893) |
+++ chrome/browser/plugin_process_host.cc (working copy) |
@@ -269,11 +269,14 @@ |
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 @@ |
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 @@ |
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 @@ |
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,10 +348,19 @@ |
} |
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) |
PluginProcessHost::PluginProcessHost(MessageLoop* main_message_loop) |
@@ -376,6 +374,21 @@ |
// 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, |