diff options
-rw-r--r-- | chrome/browser/plugin_process_host.cc | 32 | ||||
-rw-r--r-- | chrome/browser/plugin_process_host.h | 9 | ||||
-rw-r--r-- | chrome/common/ipc_message.cc | 2 | ||||
-rw-r--r-- | chrome/common/plugin_messages_internal.h | 12 | ||||
-rw-r--r-- | chrome/plugin/plugin_channel.cc | 37 | ||||
-rw-r--r-- | chrome/plugin/plugin_channel.h | 24 | ||||
-rw-r--r-- | chrome/plugin/plugin_thread.cc | 21 | ||||
-rw-r--r-- | chrome/plugin/plugin_thread.h | 4 |
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); |