Chromium Code Reviews| Index: content/browser/zygote_host/zygote_host_impl_linux.cc |
| diff --git a/content/browser/zygote_host/zygote_host_impl_linux.cc b/content/browser/zygote_host/zygote_host_impl_linux.cc |
| index 8e6cf8978427479e826f14f1a373155eab8b644b..679fb81d94d0acc3ab7137be98b5af3758c9def2 100644 |
| --- a/content/browser/zygote_host/zygote_host_impl_linux.cc |
| +++ b/content/browser/zygote_host/zygote_host_impl_linux.cc |
| @@ -301,6 +301,15 @@ pid_t ZygoteHostImpl::ForkRequest( |
| DCHECK(init_); |
| Pickle pickle; |
| + int raw_socks[2]; |
| + if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, raw_socks) != 0) { |
|
jln (very slow on Chromium)
2014/05/02 18:25:00
I think it's fine to PCHECK here, this looks like
mdempsky
2014/05/02 23:36:01
Done.
|
| + LOG(ERROR) << "Failed to create socketpair"; |
| + return base::kNullProcessHandle; |
| + } |
| + base::ScopedFD my_sock(raw_socks[0]); |
| + base::ScopedFD peer_sock(raw_socks[1]); |
| + CHECK(UnixDomainSocket::EnableReceiveProcessId(my_sock.get())); |
| + |
| pickle.WriteInt(kZygoteCommandFork); |
| pickle.WriteString(process_type); |
| pickle.WriteInt(argv.size()); |
| @@ -311,9 +320,12 @@ pid_t ZygoteHostImpl::ForkRequest( |
| pickle.WriteInt(mapping.size()); |
| std::vector<int> fds; |
| - // Scoped pointers cannot be stored in containers, so we have to use a |
| - // linked_ptr. |
| - std::vector<linked_ptr<base::ScopedFD> > autodelete_fds; |
| + ScopedVector<base::ScopedFD> autoclose_fds; |
| + |
| + // First FD to send is peer_sock. |
| + fds.push_back(peer_sock.get()); |
| + autoclose_fds.push_back(new base::ScopedFD(peer_sock.Pass())); |
| + |
| for (std::vector<FileDescriptorInfo>::const_iterator |
| i = mapping.begin(); i != mapping.end(); ++i) { |
| pickle.WriteUInt32(i->id); |
| @@ -321,8 +333,7 @@ pid_t ZygoteHostImpl::ForkRequest( |
| if (i->fd.auto_close) { |
| // Auto-close means we need to close the FDs after they have been passed |
| // to the other process. |
| - linked_ptr<base::ScopedFD> ptr(new base::ScopedFD(fds.back())); |
| - autodelete_fds.push_back(ptr); |
| + autoclose_fds.push_back(new base::ScopedFD(i->fd.fd)); |
| } |
| } |
| @@ -331,10 +342,28 @@ pid_t ZygoteHostImpl::ForkRequest( |
| base::AutoLock lock(control_lock_); |
| if (!SendMessage(pickle, &fds)) |
| return base::kNullProcessHandle; |
| + autoclose_fds.clear(); |
|
jln (very slow on Chromium)
2014/05/02 18:25:00
Hmmm, I sense a new SendMessage that takes ownersh
mdempsky
2014/05/02 23:36:01
Deferred. This is a bit tricky because we're only
|
| - // Read the reply, which pickles the PID and an optional UMA enumeration. |
| static const unsigned kMaxReplyLength = 2048; |
| char buf[kMaxReplyLength]; |
| + |
| + { |
| + ScopedVector<base::ScopedFD> recv_fds; |
| + base::ProcessId real_pid; |
| + |
| + if (UnixDomainSocket::RecvMsgWithPid( |
| + my_sock.get(), buf, sizeof(buf), &recv_fds, &real_pid) <= 0) { |
| + LOG(ERROR) << "Failed to receive PID for zygote child"; |
| + real_pid = -1; |
| + } |
| + |
| + // Always write back PID to zygote. |
| + const ssize_t n = |
| + HANDLE_EINTR(write(control_fd_, &real_pid, sizeof(real_pid))); |
| + CHECK_EQ(sizeof(real_pid), static_cast<size_t>(n)); |
| + } |
| + |
| + // Read the reply, which pickles the PID and an optional UMA enumeration. |
| const ssize_t len = ReadReply(buf, sizeof(buf)); |
| Pickle reply_pickle(buf, len); |