summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-20 03:10:51 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-20 03:10:51 +0000
commit76724d00d3498f952d945d775a3f33f751624121 (patch)
treeaa28e1bb6656708708780693443a275a2d5d43d8 /chrome/browser
parentdd86209f364eb604bb42a47dea7ae177d7166632 (diff)
downloadchromium_src-76724d00d3498f952d945d775a3f33f751624121.zip
chromium_src-76724d00d3498f952d945d775a3f33f751624121.tar.gz
chromium_src-76724d00d3498f952d945d775a3f33f751624121.tar.bz2
posix: two related changes to make plugin IPC work on POSIX.
[retry, fix windows compile failure] * use a new ChannelHandle type when passing IPC channels over IPC The current POSIX code assumes that one end of a channel is always a new child process (a renderer). For plugins we need to be able to construct channels between each of the browser, plugin, and renderer. This change augments the messages related to creating channels to allow passing in a base::FileDescriptor containing the socket. The intent is that the browser process, as the initial interchange between plugin and renderer, creates the socketpair() on their behalf and hands each their respective end of the connection. * register channel endpoint names in the global pipe map The plugin code assumes it can map from a string to a channel endpoint at basically any time. So whenever we get a channel endpoint over IPC, we install it in a global map of channel endpoints. Review URL: http://codereview.chromium.org/113157 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18888 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/plugin_process_host.cc50
-rw-r--r--chrome/browser/plugin_process_host.h10
-rw-r--r--chrome/browser/plugin_service.cc2
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc2
4 files changed, 51 insertions, 13 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index 5216755..e704a5f 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -40,6 +40,7 @@
#include "chrome/common/logging_chrome.h"
#include "chrome/common/plugin_messages.h"
#include "chrome/common/render_messages.h"
+#include "chrome/common/ipc_channel_handle.h"
#include "net/base/cookie_monster.h"
#include "net/base/file_stream.h"
#include "net/base/io_buffer.h"
@@ -53,6 +54,10 @@
#include "sandbox/src/sandbox.h"
#endif
+#if defined(OS_POSIX)
+#include "chrome/common/ipc_channel_posix.h"
+#endif
+
static const char kDefaultPluginFinderURL[] =
"http://dl.google.com/chrome/plugins/plugins2.xml";
@@ -454,7 +459,7 @@ void PluginProcessHost::OnChannelConnected(int32 peer_pid) {
void PluginProcessHost::OnChannelError() {
for (size_t i = 0; i < pending_requests_.size(); ++i) {
ReplyToRenderer(pending_requests_[i].renderer_message_filter_.get(),
- std::string(),
+ IPC::ChannelHandle(),
FilePath(),
pending_requests_[i].reply_msg);
}
@@ -468,8 +473,17 @@ void PluginProcessHost::OpenChannelToPlugin(
IPC::Message* reply_msg) {
InstanceCreated();
if (opening_channel()) {
+ // The channel is already in the process of being opened. Put
+ // this "open channel" request into a queue of requests that will
+ // be run once the channel is open.
+ //
+ // On POSIX, we'll only create the pipe when we get around to actually
+ // making this request. So the socket fd is -1 for now. (On Windows,
+ // socket_fd is unused.)
+ int socket_fd = -1;
pending_requests_.push_back(
- ChannelRequest(renderer_message_filter, mime_type, reply_msg));
+ ChannelRequest(renderer_message_filter, mime_type, reply_msg,
+ socket_fd));
return;
}
@@ -506,7 +520,8 @@ void PluginProcessHost::OnResolveProxyCompleted(IPC::Message* reply_msg,
void PluginProcessHost::ReplyToRenderer(
ResourceMessageFilter* renderer_message_filter,
- const std::string& channel, const FilePath& plugin_path,
+ const IPC::ChannelHandle& channel,
+ const FilePath& plugin_path,
IPC::Message* reply_msg) {
ViewHostMsg_OpenChannelToPlugin::WriteReplyParams(reply_msg, channel,
plugin_path);
@@ -522,29 +537,48 @@ URLRequestContext* PluginProcessHost::GetRequestContext(
void PluginProcessHost::RequestPluginChannel(
ResourceMessageFilter* renderer_message_filter,
const std::string& mime_type, IPC::Message* reply_msg) {
+ // We're about to send the request for a plugin channel.
+ // On POSIX, we create the channel endpoints here, so we can send the
+ // endpoints to the plugin and renderer.
+ int plugin_fd = -1, renderer_fd = -1;
+#if defined(OS_POSIX)
+ // On POSIX, we create the channel endpoints here.
+ IPC::SocketPair(&plugin_fd, &renderer_fd);
+#endif
+
// We can't send any sync messages from the browser because it might lead to
// a hang. However this async messages must be answered right away by the
// plugin process (i.e. unblocks a Send() call like a sync message) otherwise
// a deadlock can occur if the plugin creation request from the renderer is
// a result of a sync message by the plugin process.
PluginProcessMsg_CreateChannel* msg = new PluginProcessMsg_CreateChannel(
+#if defined(OS_POSIX)
+ // Takes ownership of plugin_fd.
+ base::FileDescriptor(plugin_fd, true),
+#endif
renderer_message_filter->GetProcessId(),
renderer_message_filter->off_the_record());
msg->set_unblock(true);
if (Send(msg)) {
sent_requests_.push(ChannelRequest(
- renderer_message_filter, mime_type, reply_msg));
+ renderer_message_filter, mime_type, reply_msg, renderer_fd));
} else {
- ReplyToRenderer(renderer_message_filter, std::string(), FilePath(),
+ ReplyToRenderer(renderer_message_filter, IPC::ChannelHandle(), FilePath(),
reply_msg);
}
}
void PluginProcessHost::OnChannelCreated(const std::string& channel_name) {
- ReplyToRenderer(sent_requests_.front().renderer_message_filter_.get(),
- channel_name,
+ const ChannelRequest& request = sent_requests_.front();
+ IPC::ChannelHandle channel_handle(channel_name
+#if defined(OS_POSIX)
+ , base::FileDescriptor(request.socket, true)
+#endif
+ );
+ ReplyToRenderer(request.renderer_message_filter_.get(),
+ channel_handle,
info_.path,
- sent_requests_.front().reply_msg);
+ request.reply_msg);
sent_requests_.pop();
}
diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h
index 56004f6..9a74dff 100644
--- a/chrome/browser/plugin_process_host.h
+++ b/chrome/browser/plugin_process_host.h
@@ -18,6 +18,7 @@
#include "chrome/browser/net/resolve_proxy_msg_helper.h"
#include "chrome/browser/renderer_host/resource_message_filter.h"
#include "chrome/common/child_process_host.h"
+#include "chrome/common/ipc_channel_handle.h"
#include "webkit/glue/webplugininfo.h"
class URLRequestContext;
@@ -65,7 +66,7 @@ class PluginProcessHost : public ChildProcessHost,
// Sends the reply to an open channel request to the renderer with the given
// channel name.
static void ReplyToRenderer(ResourceMessageFilter* renderer_message_filter,
- const std::string& channel,
+ const IPC::ChannelHandle& channel,
const FilePath& plugin_path,
IPC::Message* reply_msg);
@@ -113,12 +114,15 @@ class PluginProcessHost : public ChildProcessHost,
struct ChannelRequest {
ChannelRequest(ResourceMessageFilter* renderer_message_filter,
- const std::string& m, IPC::Message* r) :
+ const std::string& m, IPC::Message* r,
+ int s) :
mime_type(m), reply_msg(r),
- renderer_message_filter_(renderer_message_filter) { }
+ renderer_message_filter_(renderer_message_filter),
+ socket(s) { }
std::string mime_type;
IPC::Message* reply_msg;
scoped_refptr<ResourceMessageFilter> renderer_message_filter_;
+ int socket;
};
// These are channel requests that we are waiting to send to the
diff --git a/chrome/browser/plugin_service.cc b/chrome/browser/plugin_service.cc
index 773698a..c49d56d 100644
--- a/chrome/browser/plugin_service.cc
+++ b/chrome/browser/plugin_service.cc
@@ -167,7 +167,7 @@ void PluginService::OpenChannelToPlugin(
plugin_host->OpenChannelToPlugin(renderer_msg_filter, mime_type, reply_msg);
} else {
PluginProcessHost::ReplyToRenderer(renderer_msg_filter,
- std::string(),
+ IPC::ChannelHandle(),
FilePath(),
reply_msg);
}
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index 2121378..4728b17 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -176,7 +176,7 @@ void ResourceMessageFilter::OnFilterAdded(IPC::Channel* channel) {
// Called on the IPC thread:
void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) {
- DCHECK(!handle());
+ DCHECK(!handle()) << " " << handle();
base::ProcessHandle peer_handle;
if (!base::OpenProcessHandle(peer_pid, &peer_handle)) {
NOTREACHED();