summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/plugin_process_host.cc32
-rw-r--r--chrome/browser/plugin_process_host.h9
-rw-r--r--chrome/common/ipc_message.cc2
-rw-r--r--chrome/common/plugin_messages_internal.h12
-rw-r--r--chrome/plugin/plugin_channel.cc37
-rw-r--r--chrome/plugin/plugin_channel.h24
-rw-r--r--chrome/plugin/plugin_thread.cc21
-rw-r--r--chrome/plugin/plugin_thread.h4
8 files changed, 69 insertions, 72 deletions
diff --git a/chrome/browser/plugin_process_host.cc b/chrome/browser/plugin_process_host.cc
index d1103a0..55885bd 100644
--- a/chrome/browser/plugin_process_host.cc
+++ b/chrome/browser/plugin_process_host.cc
@@ -472,14 +472,8 @@ void PluginProcessHost::OpenChannelToPlugin(
// 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,
- socket_fd));
+ ChannelRequest(renderer_message_filter, mime_type, reply_msg));
return;
}
@@ -533,44 +527,28 @@ 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_fd));
+ renderer_message_filter, mime_type, reply_msg));
} else {
ReplyToRenderer(renderer_message_filter, IPC::ChannelHandle(), FilePath(),
reply_msg);
}
}
-void PluginProcessHost::OnChannelCreated(const std::string& channel_name) {
+void PluginProcessHost::OnChannelCreated(
+ const IPC::ChannelHandle& channel_handle) {
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,
diff --git a/chrome/browser/plugin_process_host.h b/chrome/browser/plugin_process_host.h
index 9a74dff..72a5d78 100644
--- a/chrome/browser/plugin_process_host.h
+++ b/chrome/browser/plugin_process_host.h
@@ -97,7 +97,7 @@ class PluginProcessHost : public ChildProcessHost,
const std::string& mime_type,
IPC::Message* reply_msg);
// Message handlers.
- void OnChannelCreated(const std::string& channel_name);
+ void OnChannelCreated(const IPC::ChannelHandle& channel_handle);
void OnGetPluginFinderUrl(std::string* plugin_finder_url);
void OnGetCookies(uint32 request_context, const GURL& url,
std::string* cookies);
@@ -114,15 +114,12 @@ class PluginProcessHost : public ChildProcessHost,
struct ChannelRequest {
ChannelRequest(ResourceMessageFilter* renderer_message_filter,
- const std::string& m, IPC::Message* r,
- int s) :
+ const std::string& m, IPC::Message* r) :
mime_type(m), reply_msg(r),
- renderer_message_filter_(renderer_message_filter),
- socket(s) { }
+ renderer_message_filter_(renderer_message_filter) { }
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/common/ipc_message.cc b/chrome/common/ipc_message.cc
index d7cc49d..6b9ded0 100644
--- a/chrome/common/ipc_message.cc
+++ b/chrome/common/ipc_message.cc
@@ -109,7 +109,7 @@ bool Message::ReadFileDescriptor(void** iter,
return false;
descriptor->fd = file_descriptor_set->GetDescriptorAt(descriptor_index);
- descriptor->auto_close = false;
+ descriptor->auto_close = true;
return descriptor->fd >= 0;
}
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index 500bd93..9eed897 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -20,19 +20,9 @@ IPC_BEGIN_MESSAGES(PluginProcess)
// PluginProcessHostMsg_ChannelCreated message. The renderer's process_id is
// passed so that the plugin process reuses an existing channel to that
// process if it exists.
- // It would be nice to use #ifdefs inside the parameter list to not need to
- // duplicate this across POSIX/Windows but the Visual Studio compiler doesn't
- // like that.
-#if defined(OS_WIN)
IPC_MESSAGE_CONTROL2(PluginProcessMsg_CreateChannel,
int /* process_id */,
bool /* off_the_record */)
-#elif defined(OS_POSIX)
- IPC_MESSAGE_CONTROL3(PluginProcessMsg_CreateChannel,
- base::FileDescriptor /* socket for new channel */,
- int /* process_id */,
- bool /* off_the_record */)
-#endif
// Allows a chrome plugin loaded in the browser process to send arbitrary
// data to an instance of the same plugin loaded in a plugin process.
@@ -57,7 +47,7 @@ IPC_END_MESSAGES(PluginProcess)
IPC_BEGIN_MESSAGES(PluginProcessHost)
// Response to a PluginProcessMsg_CreateChannel message.
IPC_MESSAGE_CONTROL1(PluginProcessHostMsg_ChannelCreated,
- std::string /* channel_name */)
+ IPC::ChannelHandle /* channel_handle */)
IPC_SYNC_MESSAGE_CONTROL0_1(PluginProcessHostMsg_GetPluginFinderUrl,
std::string /* plugin finder URL */)
diff --git a/chrome/plugin/plugin_channel.cc b/chrome/plugin/plugin_channel.cc
index b9e7a52..6264af5 100644
--- a/chrome/plugin/plugin_channel.cc
+++ b/chrome/plugin/plugin_channel.cc
@@ -18,18 +18,11 @@
#endif
PluginChannel* PluginChannel::GetPluginChannel(
- int process_id, MessageLoop* ipc_message_loop, int channel_fd) {
+ int process_id, MessageLoop* ipc_message_loop) {
// map renderer's process id to a (single) channel to that process
std::string channel_name = StringPrintf(
"%d.r%d", base::GetCurrentProcId(), process_id);
-#if defined(OS_POSIX)
- // If we were provided an already-open channel, associate it with
- // the channel name in this process's name<->socket map.
- if (channel_fd > 0)
- IPC::AddChannelSocket(channel_name, channel_fd);
-#endif
-
return static_cast<PluginChannel*>(PluginChannelBase::GetChannel(
channel_name,
IPC::Channel::MODE_SERVER,
@@ -38,8 +31,13 @@ PluginChannel* PluginChannel::GetPluginChannel(
false));
}
-PluginChannel::PluginChannel() : renderer_handle_(0), in_send_(0),
- off_the_record_(false) {
+PluginChannel::PluginChannel()
+ : renderer_handle_(0),
+#if defined(OS_POSIX)
+ renderer_fd_(-1),
+#endif
+ in_send_(0),
+ off_the_record_(false) {
SendUnblockingOnlyDuringDispatch();
ChildProcess::current()->AddRefProcess();
const CommandLine* command_line = CommandLine::ForCurrentProcess();
@@ -49,6 +47,12 @@ PluginChannel::PluginChannel() : renderer_handle_(0), in_send_(0),
PluginChannel::~PluginChannel() {
if (renderer_handle_)
base::CloseProcessHandle(renderer_handle_);
+#if defined(OS_POSIX)
+ // If we still have the FD, close it.
+ if (renderer_fd_ != -1) {
+ close(renderer_fd_);
+ }
+#endif
ChildProcess::current()->ReleaseProcess();
}
@@ -144,3 +148,16 @@ void PluginChannel::CleanUp() {
plugin_stubs_.clear();
}
+
+bool PluginChannel::Init(MessageLoop* ipc_message_loop, bool create_pipe_now) {
+#if defined(OS_POSIX)
+ // This gets called when the PluginChannel is initially created. At this
+ // point, create the socketpair and assign the plugin side FD to the channel
+ // name. Keep the renderer side FD as a member variable in the PluginChannel
+ // to be able to transmit it through IPC.
+ int plugin_fd;
+ IPC::SocketPair(&plugin_fd, &renderer_fd_);
+ IPC::AddChannelSocket(channel_name(), plugin_fd);
+#endif
+ return PluginChannelBase::Init(ipc_message_loop, create_pipe_now);
+}
diff --git a/chrome/plugin/plugin_channel.h b/chrome/plugin/plugin_channel.h
index 21373fb..02b619e 100644
--- a/chrome/plugin/plugin_channel.h
+++ b/chrome/plugin/plugin_channel.h
@@ -19,8 +19,7 @@ class PluginChannel : public PluginChannelBase {
// POSIX only: If |channel_fd| > 0, use that file descriptor for the
// channel socket.
static PluginChannel* GetPluginChannel(int process_id,
- MessageLoop* ipc_message_loop,
- int channel_fd);
+ MessageLoop* ipc_message_loop);
~PluginChannel();
@@ -30,6 +29,18 @@ class PluginChannel : public PluginChannelBase {
base::ProcessHandle renderer_handle() const { return renderer_handle_; }
int GenerateRouteID();
+#if defined(OS_POSIX)
+ // When first created, the PluginChannel gets assigned the file descriptor
+ // for the renderer.
+ // After the first time we pass it through the IPC, we don't need it anymore,
+ // and we close it. At that time, we reset renderer_fd_ to -1.
+ int DisownRendererFd() {
+ int value = renderer_fd_;
+ renderer_fd_ = -1;
+ return value;
+ }
+#endif
+
bool in_send() { return in_send_ != 0; }
bool off_the_record() { return off_the_record_; }
@@ -42,6 +53,9 @@ class PluginChannel : public PluginChannelBase {
virtual void CleanUp();
+ // Overrides PluginChannelBase::Init.
+ virtual bool Init(MessageLoop* ipc_message_loop, bool create_pipe_now);
+
private:
// Called on the plugin thread
PluginChannel();
@@ -59,6 +73,12 @@ class PluginChannel : public PluginChannelBase {
// Handle to the renderer process who is on the other side of the channel.
base::ProcessHandle renderer_handle_;
+#if defined(OS_POSIX)
+ // FD for the renderer end of the pipe. It is stored until we send it over
+ // IPC after which it is cleared. It will be closed by the IPC mechanism.
+ int renderer_fd_;
+#endif
+
int in_send_; // Tracks if we're in a Send call.
bool log_messages_; // True if we should log sent and received messages.
bool off_the_record_; // True if the renderer is in off the record mode.
diff --git a/chrome/plugin/plugin_thread.cc b/chrome/plugin/plugin_thread.cc
index 2f9c2ec..2701f5b 100644
--- a/chrome/plugin/plugin_thread.cc
+++ b/chrome/plugin/plugin_thread.cc
@@ -103,24 +103,23 @@ void PluginThread::CleanUp() {
}
void PluginThread::OnCreateChannel(
-#if defined(OS_POSIX)
- base::FileDescriptor socket,
-#endif
int process_id,
bool off_the_record) {
- int fd = -1;
-#if defined(OS_POSIX)
- fd = socket.fd;
-#endif
- std::string channel_name;
scoped_refptr<PluginChannel> channel =
- PluginChannel::GetPluginChannel(process_id, owner_loop(), fd);
+ PluginChannel::GetPluginChannel(process_id, owner_loop());
+ IPC::ChannelHandle channel_handle;
if (channel.get()) {
- channel_name = channel->channel_name();
+ channel_handle.name = channel->channel_name();
+#if defined(OS_POSIX)
+ // On POSIX, pass the renderer-side FD. Also mark it as auto-close so that
+ // it gets closed after it has been sent.
+ int renderer_fd = channel->DisownRendererFd();
+ channel_handle.socket = base::FileDescriptor(renderer_fd, true);
+#endif
channel->set_off_the_record(off_the_record);
}
- Send(new PluginProcessHostMsg_ChannelCreated(channel_name));
+ Send(new PluginProcessHostMsg_ChannelCreated(channel_handle));
}
void PluginThread::OnPluginMessage(const std::vector<unsigned char> &data) {
diff --git a/chrome/plugin/plugin_thread.h b/chrome/plugin/plugin_thread.h
index 911940a..e9074aa 100644
--- a/chrome/plugin/plugin_thread.h
+++ b/chrome/plugin/plugin_thread.h
@@ -37,11 +37,7 @@ class PluginThread : public ChildThread {
virtual void CleanUp();
// Callback for when a channel has been created.
- // On POSIX, |socket| is the channel endpoint socket.
void OnCreateChannel(
-#if defined(OS_POSIX)
- base::FileDescriptor socket,
-#endif
int process_id,
bool off_the_record);
void OnPluginMessage(const std::vector<uint8> &data);