Commit 3fcdea5f authored by Albert J. Wong's avatar Albert J. Wong Committed by Commit Bot

memlog: PlatformChannelPair for initial data pipe

Leverages mojo EDK utils to remove one platform divergence in pipe creation,
and then another within the Posix world for handling sendmsg vs write which
differs signficantly between SysV-ish Linux and BSDish OsX.

Bug: 
Change-Id: I27391043a05e0c917bed1f99acd3811ef92b2d19
Reviewed-on: https://chromium-review.googlesource.com/578381Reviewed-by: default avatarAlbert J. Wong <ajwong@chromium.org>
Reviewed-by: default avatarBrett Wilson <brettw@chromium.org>
Commit-Queue: Albert J. Wong <ajwong@chromium.org>
Cr-Commit-Position: refs/heads/master@{#488365}
parent 78b6f3ea
......@@ -18,14 +18,7 @@
#include "mojo/edk/embedder/platform_channel_pair.h"
#include "mojo/public/cpp/system/platform_handle.h"
#if defined(OS_LINUX)
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#if defined(OS_POSIX)
#include "base/files/scoped_file.h"
#include "base/process/process_metrics.h"
#include "base/third_party/valgrind/valgrind.h"
......@@ -149,30 +142,14 @@ void ProfilingProcessHost::Launch() {
mojo::edk::PlatformChannelPair control_channel;
mojo::edk::HandlePassingInformation handle_passing_info;
// TODO(brettw) most of this logic can be replaced with PlatformChannelPair.
// Create the socketpair for the low level memlog pipe.
mojo::edk::PlatformChannelPair data_channel;
pipe_id_ = data_channel.PrepareToPassClientHandleToChildProcessAsString(
&handle_passing_info);
#if defined(OS_WIN)
base::Process process = base::Process::Current();
pipe_id_ = base::IntToString(static_cast<int>(process.Pid()));
base::CommandLine profiling_cmd = MakeProfilingCommandLine(pipe_id_);
#else
mojo::edk::ScopedPlatformHandle child_end = data_channel.PassClientHandle();
// Create the socketpair for the low level memlog pipe.
// TODO(ajwong): Should this use base/posix/unix_domain_socket_linux.h?
int memlog_fds[2];
PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, memlog_fds) == 0);
PCHECK(fcntl(memlog_fds[0], F_SETFL, O_NONBLOCK) == 0);
PCHECK(fcntl(memlog_fds[1], F_SETFL, O_NONBLOCK) == 0);
// Store one end for our message sender to use.
base::ScopedFD child_end(memlog_fds[1]);
// TODO(brettw) need to get rid of pipe_id when we can share over Mojo.
pipe_id_ = base::IntToString(memlog_fds[0]);
handle_passing_info.emplace_back(child_end.get(), child_end.get());
base::CommandLine profiling_cmd =
MakeProfilingCommandLine(base::IntToString(child_end.get()));
#endif
base::CommandLine profiling_cmd = MakeProfilingCommandLine(pipe_id_);
// Keep the server handle, pass the client handle to the child.
pending_control_connection_ = control_channel.PassServerHandle();
......@@ -184,13 +161,16 @@ void ProfilingProcessHost::Launch() {
options.handles_to_inherit = &handle_passing_info;
#elif defined(OS_POSIX)
options.fds_to_remap = &handle_passing_info;
#if defined(OS_LINUX)
options.kill_on_parent_death = true;
#endif
#else
#error Unsupported OS.
#endif
process_ = base::LaunchProcess(profiling_cmd, options);
StartMemlogSender(pipe_id_);
StartMemlogSender(
base::IntToString(data_channel.PassServerHandle().release().handle));
}
void ProfilingProcessHost::EnsureControlChannelExists() {
......
include_rules = [
"+mojo/edk/embedder",
]
......@@ -10,16 +10,14 @@
#include "base/posix/unix_domain_socket_linux.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/common/profiling/memlog_stream.h"
#include "mojo/edk/embedder/platform_channel_utils_posix.h"
namespace profiling {
MemlogSenderPipe::MemlogSenderPipe(const std::string& pipe_id) {
int fd;
CHECK(base::StringToInt(pipe_id, &fd));
fd_.reset(fd);
static std::vector<int> dummy_instance;
dummy_for_send_ = &dummy_instance;
handle_.reset(mojo::edk::PlatformHandle(fd));
}
MemlogSenderPipe::~MemlogSenderPipe() {
......@@ -31,7 +29,7 @@ bool MemlogSenderPipe::Connect() {
}
bool MemlogSenderPipe::Send(const void* data, size_t sz) {
return base::UnixDomainSocket::SendMsg(fd_.get(), data, sz, *dummy_for_send_);
return mojo::edk::PlatformChannelWrite(handle_.get(), data, sz);
}
} // namespace profiling
......@@ -8,8 +8,8 @@
#include <string>
#include <vector>
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
namespace profiling {
......@@ -23,11 +23,7 @@ class MemlogSenderPipe {
bool Send(const void* data, size_t sz);
private:
base::ScopedFD fd_;
// Make base::UnixDomainSocket::SendMsg happy.
// TODO(ajwong): This is not really threadsafe. Fix.
std::vector<int>* dummy_for_send_ = nullptr;
mojo::edk::ScopedPlatformHandle handle_;
DISALLOW_COPY_AND_ASSIGN(MemlogSenderPipe);
};
......
......@@ -10,6 +10,8 @@
#include "base/posix/unix_domain_socket_linux.h"
#include "base/threading/thread.h"
#include "chrome/profiling/memlog_stream_receiver.h"
#include "mojo/edk/embedder/platform_channel_utils_posix.h"
#include "mojo/edk/embedder/platform_handle.h"
namespace profiling {
......@@ -25,20 +27,18 @@ const int kReadBufferSize = 1024 * 64;
} // namespace
MemlogReceiverPipe::MemlogReceiverPipe(base::ScopedFD fd)
: fd_(std::move(fd)),
: handle_(mojo::edk::PlatformHandle(fd.release())),
controller_(FROM_HERE),
read_buffer_(new char[kReadBufferSize]) {
static std::vector<base::ScopedFD> dummy_instance;
dummy_for_receive_ = &dummy_instance;
}
read_buffer_(new char[kReadBufferSize]) {}
MemlogReceiverPipe::~MemlogReceiverPipe() {}
void MemlogReceiverPipe::ReadUntilBlocking() {
ssize_t bytes_read = 0;
do {
bytes_read = base::UnixDomainSocket::RecvMsg(
fd_.get(), read_buffer_.get(), kReadBufferSize, dummy_for_receive_);
std::deque<mojo::edk::PlatformHandle> dummy_for_receive;
bytes_read = mojo::edk::PlatformChannelRecvmsg(
handle_.get(), read_buffer_.get(), kReadBufferSize, &dummy_for_receive);
if (bytes_read > 0) {
receiver_task_runner_->PostTask(
FROM_HERE,
......
......@@ -12,6 +12,7 @@
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "build/build_config.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
namespace base {
class TaskRunner;
......@@ -41,7 +42,7 @@ class MemlogReceiverPipe
friend class base::RefCountedThreadSafe<MemlogReceiverPipe>;
~MemlogReceiverPipe();
base::ScopedFD fd_;
mojo::edk::ScopedPlatformHandle handle_;
base::MessageLoopForIO::FileDescriptorWatcher controller_;
std::unique_ptr<char[]> read_buffer_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment