summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 01:41:50 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-01 01:41:50 +0000
commitc4eac73e104ccd5156a15a3602cb45343853d48d (patch)
treeb6a81277d4b83489b713499b9f1529b0ed05dccf
parent29a596b68aa20e3017985d1dc5cbbdceeef6017c (diff)
downloadchromium_src-c4eac73e104ccd5156a15a3602cb45343853d48d.zip
chromium_src-c4eac73e104ccd5156a15a3602cb45343853d48d.tar.gz
chromium_src-c4eac73e104ccd5156a15a3602cb45343853d48d.tar.bz2
Linux: terminate clipboard handling on the UI thread.
After discussing with various people, I think we're going to do this in the short term at least. Currently we're calling into GTK from the IO thread and Bad Things Happen when one does that. We would like to write an Xlib, fully asynchronous system for dealing with the clipboard (and to get the clipboard stuff out of base!). That would let us avoid sending the selection over the IPC channel each time it updates too. However, that's going to be a lot of work and we have crashing browsers happening /right now/. Also, Evan thinks that maybe we don't have the deadlock situation on Linux that we do on Windows with terminating sync requests from the renderer on the UI thread. http://codereview.chromium.org/100238 BUG=9865 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@15028 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc63
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h18
-rw-r--r--chrome/browser/renderer_host/resource_message_filter_gtk.cc87
3 files changed, 141 insertions, 27 deletions
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index aee7604..804042f 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -264,13 +264,16 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& message) {
OnClipboardWriteObjects)
IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardWriteObjectsSync,
OnClipboardWriteObjects)
- IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardIsFormatAvailable,
- OnClipboardIsFormatAvailable)
- IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadText, OnClipboardReadText)
- IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadAsciiText,
- OnClipboardReadAsciiText)
- IPC_MESSAGE_HANDLER(ViewHostMsg_ClipboardReadHTML,
- OnClipboardReadHTML)
+
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ClipboardIsFormatAvailable,
+ OnClipboardIsFormatAvailable)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ClipboardReadText,
+ OnClipboardReadText)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ClipboardReadAsciiText,
+ OnClipboardReadAsciiText)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(ViewHostMsg_ClipboardReadHTML,
+ OnClipboardReadHTML)
+
IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromExtension,
OnGetMimeTypeFromExtension)
IPC_MESSAGE_HANDLER(ViewHostMsg_GetMimeTypeFromFile,
@@ -555,27 +558,51 @@ void ResourceMessageFilter::OnClipboardWriteObjects(
new WriteClipboardTask(long_living_objects));
}
+#if !defined(OS_LINUX)
+// On non-Linux platforms, clipboard actions can be performed on the IO thread.
+// On Linux, since the clipboard is linked with GTK, we either have to do this
+// with GTK on the UI thread, or with Xlib on the BACKGROUND_X11 thread. In an
+// ideal world, we would do the latter. However, for now we're going to
+// terminate these calls on the UI thread. This risks deadlock in the case of
+// plugins, but it's better than crashing which is what doing on the IO thread
+// gives us.
+//
+// See resource_message_filter_gtk.cc for the Linux implementation of these
+// functions.
+
void ResourceMessageFilter::OnClipboardIsFormatAvailable(
- Clipboard::FormatType format, bool* result) {
- DCHECK(result);
- *result = GetClipboardService()->IsFormatAvailable(format);
+ Clipboard::FormatType format, IPC::Message* reply) {
+ const bool result = GetClipboardService()->IsFormatAvailable(format);
+ ViewHostMsg_ClipboardIsFormatAvailable::WriteReplyParams(reply, result);
+ Send(reply);
}
-void ResourceMessageFilter::OnClipboardReadText(string16* result) {
- GetClipboardService()->ReadText(result);
+void ResourceMessageFilter::OnClipboardReadText(IPC::Message* reply) {
+ string16 result;
+ GetClipboardService()->ReadText(&result);
+ ViewHostMsg_ClipboardReadText::WriteReplyParams(reply, result);
+ Send(reply);
}
-void ResourceMessageFilter::OnClipboardReadAsciiText(std::string* result) {
- GetClipboardService()->ReadAsciiText(result);
+void ResourceMessageFilter::OnClipboardReadAsciiText(IPC::Message* reply) {
+ std::string result;
+ GetClipboardService()->ReadAsciiText(&result);
+ ViewHostMsg_ClipboardReadAsciiText::WriteReplyParams(reply, result);
+ Send(reply);
}
-void ResourceMessageFilter::OnClipboardReadHTML(string16* markup,
- GURL* src_url) {
+void ResourceMessageFilter::OnClipboardReadHTML(IPC::Message* reply) {
std::string src_url_str;
- GetClipboardService()->ReadHTML(markup, &src_url_str);
- *src_url = GURL(src_url_str);
+ string16 markup;
+ GetClipboardService()->ReadHTML(&markup, &src_url_str);
+ const GURL src_url = GURL(src_url_str);
+
+ ViewHostMsg_ClipboardReadHTML::WriteReplyParams(reply, markup, src_url);
+ Send(reply);
}
+#endif
+
void ResourceMessageFilter::OnGetMimeTypeFromExtension(
const FilePath::StringType& ext, std::string* mime_type) {
net::GetMimeTypeFromExtension(ext, mime_type);
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 1ce2b95..74181bf 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -151,10 +151,13 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
void OnReceiveContextMenuMsg(const IPC::Message& msg);
// Clipboard messages
void OnClipboardWriteObjects(const Clipboard::ObjectMap& objects);
- void OnClipboardIsFormatAvailable(Clipboard::FormatType format, bool* result);
- void OnClipboardReadText(string16* result);
- void OnClipboardReadAsciiText(std::string* result);
- void OnClipboardReadHTML(string16* markup, GURL* src_url);
+
+ void OnClipboardIsFormatAvailable(Clipboard::FormatType format,
+ IPC::Message* reply);
+ void OnClipboardReadText(IPC::Message* reply);
+ void OnClipboardReadAsciiText(IPC::Message* reply);
+ void OnClipboardReadHTML(IPC::Message* reply);
+
void OnGetWindowRect(gfx::NativeViewId window, IPC::Message* reply);
void OnGetRootWindowRect(gfx::NativeViewId window, IPC::Message* reply);
void OnGetMimeTypeFromExtension(const FilePath::StringType& ext,
@@ -203,10 +206,15 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
void OnExtensionPostMessage(int port_id, const std::string& message);
#if defined(OS_LINUX)
- void SendBackgroundX11Reply(IPC::Message* reply_msg);
+ void SendDelayedReply(IPC::Message* reply_msg);
void DoOnGetScreenInfo(gfx::NativeViewId view, IPC::Message* reply_msg);
void DoOnGetWindowRect(gfx::NativeViewId view, IPC::Message* reply_msg);
void DoOnGetRootWindowRect(gfx::NativeViewId view, IPC::Message* reply_msg);
+ void DoOnClipboardIsFormatAvailable(Clipboard::FormatType format,
+ IPC::Message* reply_msg);
+ void DoOnClipboardReadText(IPC::Message* reply_msg);
+ void DoOnClipboardReadAsciiText(IPC::Message* reply_msg);
+ void DoOnClipboardReadHTML(IPC::Message* reply_msg);
#endif
// We have our own clipboard service because we want to access the clipboard
diff --git a/chrome/browser/renderer_host/resource_message_filter_gtk.cc b/chrome/browser/renderer_host/resource_message_filter_gtk.cc
index 86c6f14..dc00486 100644
--- a/chrome/browser/renderer_host/resource_message_filter_gtk.cc
+++ b/chrome/browser/renderer_host/resource_message_filter_gtk.cc
@@ -4,8 +4,10 @@
#include "chrome/browser/renderer_host/resource_message_filter.h"
+#include "base/clipboard.h"
#include "base/gfx/gtk_native_view_id_manager.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/common/clipboard_service.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/x11_util.h"
@@ -19,7 +21,7 @@ using WebKit::WebScreenInfoFactory;
// http://crbug.com/9060 for more details.
// Called on the IO thread.
-void ResourceMessageFilter::SendBackgroundX11Reply(IPC::Message* reply_msg) {
+void ResourceMessageFilter::SendDelayedReply(IPC::Message* reply_msg) {
Send(reply_msg);
}
@@ -33,7 +35,7 @@ void ResourceMessageFilter::DoOnGetScreenInfo(gfx::NativeViewId view,
ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(
FROM_HERE, NewRunnableMethod(
- this, &ResourceMessageFilter::SendBackgroundX11Reply, reply_msg));
+ this, &ResourceMessageFilter::SendDelayedReply, reply_msg));
}
// Called on the BACKGROUND_X11 thread.
@@ -57,7 +59,7 @@ void ResourceMessageFilter::DoOnGetWindowRect(gfx::NativeViewId view,
ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(
FROM_HERE, NewRunnableMethod(
- this, &ResourceMessageFilter::SendBackgroundX11Reply, reply_msg));
+ this, &ResourceMessageFilter::SendDelayedReply, reply_msg));
}
// Return the top-level parent of the given window. Called on the
@@ -96,7 +98,58 @@ void ResourceMessageFilter::DoOnGetRootWindowRect(gfx::NativeViewId view,
ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(
FROM_HERE, NewRunnableMethod(
- this, &ResourceMessageFilter::SendBackgroundX11Reply, reply_msg));
+ this, &ResourceMessageFilter::SendDelayedReply, reply_msg));
+}
+
+// Called on the UI thread.
+void ResourceMessageFilter::DoOnClipboardIsFormatAvailable(
+ Clipboard::FormatType format, IPC::Message* reply_msg) {
+ const bool result = GetClipboardService()->IsFormatAvailable(format);
+
+ ViewHostMsg_ClipboardIsFormatAvailable::WriteReplyParams(reply_msg, result);
+
+ ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::SendDelayedReply, reply_msg));
+}
+
+// Called on the UI thread.
+void ResourceMessageFilter::DoOnClipboardReadText(IPC::Message* reply_msg) {
+ string16 result;
+ GetClipboardService()->ReadText(&result);
+
+ ViewHostMsg_ClipboardReadText::WriteReplyParams(reply_msg, result);
+
+ ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::SendDelayedReply, reply_msg));
+}
+
+// Called on the UI thread.
+void ResourceMessageFilter::DoOnClipboardReadAsciiText(
+ IPC::Message* reply_msg) {
+ std::string result;
+ GetClipboardService()->ReadAsciiText(&result);
+
+ ViewHostMsg_ClipboardReadAsciiText::WriteReplyParams(reply_msg, result);
+
+ ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::SendDelayedReply, reply_msg));
+}
+
+// Called on the UI thread.
+void ResourceMessageFilter::DoOnClipboardReadHTML(IPC::Message* reply_msg) {
+ std::string src_url_str;
+ string16 markup;
+ GetClipboardService()->ReadHTML(&markup, &src_url_str);
+ const GURL src_url = GURL(src_url_str);
+
+ ViewHostMsg_ClipboardReadHTML::WriteReplyParams(reply_msg, markup, src_url);
+
+ ChromeThread::GetMessageLoop(ChromeThread::IO)->PostTask(
+ FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::SendDelayedReply, reply_msg));
}
// Called on the IO thread.
@@ -122,3 +175,29 @@ void ResourceMessageFilter::OnGetRootWindowRect(gfx::NativeViewId view,
FROM_HERE, NewRunnableMethod(
this, &ResourceMessageFilter::DoOnGetRootWindowRect, view, reply_msg));
}
+
+// Called on the IO thread.
+void ResourceMessageFilter::OnClipboardIsFormatAvailable(
+ Clipboard::FormatType format, IPC::Message* reply_msg) {
+ ui_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::DoOnClipboardIsFormatAvailable, format,
+ reply_msg));
+}
+
+// Called on the IO thread.
+void ResourceMessageFilter::OnClipboardReadText(IPC::Message* reply_msg) {
+ ui_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::DoOnClipboardReadText, reply_msg));
+}
+
+// Called on the IO thread.
+void ResourceMessageFilter::OnClipboardReadAsciiText(IPC::Message* reply_msg) {
+ ui_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::DoOnClipboardReadAsciiText, reply_msg));
+}
+
+// Called on the IO thread.
+void ResourceMessageFilter::OnClipboardReadHTML(IPC::Message* reply_msg) {
+ ui_loop()->PostTask(FROM_HERE, NewRunnableMethod(
+ this, &ResourceMessageFilter::DoOnClipboardReadHTML, reply_msg));
+}