Mojo: Refactor PlatformChannel stuff.

- Remove PlatformServerChannel/PlatformClientChannel.
- Add PlatformChannelPair (move stuff formerly in PlatformServerChannel
  into this).

It became apparent that my previous plan to make this work on Windows
wasn't work nicely. On the one hand, on Vista+, we can basically make
things work like POSIX (created the channels in the parent and connect
them, and send a channel to a child). On the other, on XP, to be secure
you need to do more work (the channels aren't connected or authenticated
initially), so you'd need much more machinery (to wait for connection,
to authenticate, etc.).

So I'll go for a different mechanism to make things work on XP. The
assumption from the Mojo embedder API will be that it's given a channel
handle that's already been connected, authenticated, etc. (which will be
taken care of by other means). This will add flexibility in other ways
as well (e.g., make Mojo IPC more happily coexist with Chrome IPC -- you
should be able to pass a handle over Chrome IPC to set up Mojo IPC).

Still to do: Move PlatformChannelPair into its own files.

R=darin@chromium.org

Review URL: https://codereview.chromium.org/134373005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244223 0039d316-1c4b-4281-b951-d872f2087c98
parent 84c06f09
...@@ -29,21 +29,22 @@ void MultiprocessTestBase::SetUp() { ...@@ -29,21 +29,22 @@ void MultiprocessTestBase::SetUp() {
// TODO(vtl): Not implemented on Windows yet. // TODO(vtl): Not implemented on Windows yet.
#if defined(OS_POSIX) #if defined(OS_POSIX)
platform_server_channel = platform_channel_pair_.reset(new system::PlatformChannelPair());
system::PlatformServerChannel::Create("TestChannel"); server_platform_channel = platform_channel_pair_->CreateServerChannel();
#endif #endif
} }
void MultiprocessTestBase::TearDown() { void MultiprocessTestBase::TearDown() {
CHECK_EQ(test_child_handle_, base::kNullProcessHandle); CHECK_EQ(test_child_handle_, base::kNullProcessHandle);
platform_server_channel.reset(); server_platform_channel.reset();
platform_channel_pair_.reset();
MultiProcessTest::TearDown(); MultiProcessTest::TearDown();
} }
void MultiprocessTestBase::StartChild(const std::string& test_child_name) { void MultiprocessTestBase::StartChild(const std::string& test_child_name) {
CHECK(platform_server_channel.get()); CHECK(platform_channel_pair_.get());
CHECK(!test_child_name.empty()); CHECK(!test_child_name.empty());
CHECK_EQ(test_child_handle_, base::kNullProcessHandle); CHECK_EQ(test_child_handle_, base::kNullProcessHandle);
...@@ -52,8 +53,8 @@ void MultiprocessTestBase::StartChild(const std::string& test_child_name) { ...@@ -52,8 +53,8 @@ void MultiprocessTestBase::StartChild(const std::string& test_child_name) {
#if defined(OS_POSIX) #if defined(OS_POSIX)
CommandLine unused(CommandLine::NO_PROGRAM); CommandLine unused(CommandLine::NO_PROGRAM);
base::FileHandleMappingVector fds_to_map; base::FileHandleMappingVector fds_to_map;
platform_server_channel->GetDataNeededToPassClientChannelToChildProcess( platform_channel_pair_->PrepareToPassClientChannelToChildProcess(&unused,
&unused, &fds_to_map); &fds_to_map);
test_child_handle_ = SpawnChild(test_child_main, fds_to_map, false); test_child_handle_ = SpawnChild(test_child_main, fds_to_map, false);
#elif defined(OS_WIN) #elif defined(OS_WIN)
test_child_handle_ = SpawnChild(test_child_main, false); test_child_handle_ = SpawnChild(test_child_main, false);
...@@ -62,7 +63,7 @@ void MultiprocessTestBase::StartChild(const std::string& test_child_name) { ...@@ -62,7 +63,7 @@ void MultiprocessTestBase::StartChild(const std::string& test_child_name) {
#endif #endif
// TODO(vtl): Not implemented on Windows yet. // TODO(vtl): Not implemented on Windows yet.
#if defined(OS_POSIX) #if defined(OS_POSIX)
platform_server_channel->ChildProcessLaunched(); platform_channel_pair_->ChildProcessLaunched();
#endif #endif
CHECK_NE(test_child_handle_, base::kNullProcessHandle); CHECK_NE(test_child_handle_, base::kNullProcessHandle);
...@@ -82,14 +83,14 @@ int MultiprocessTestBase::WaitForChildShutdown() { ...@@ -82,14 +83,14 @@ int MultiprocessTestBase::WaitForChildShutdown() {
CommandLine MultiprocessTestBase::MakeCmdLine(const std::string& procname, CommandLine MultiprocessTestBase::MakeCmdLine(const std::string& procname,
bool debug_on_start) { bool debug_on_start) {
CHECK(platform_server_channel.get()); CHECK(platform_channel_pair_.get());
CommandLine command_line = CommandLine command_line =
base::MultiProcessTest::MakeCmdLine(procname, debug_on_start); base::MultiProcessTest::MakeCmdLine(procname, debug_on_start);
// TODO(vtl): Not implemented on Windows yet. // TODO(vtl): Not implemented on Windows yet.
#if defined(OS_POSIX) #if defined(OS_POSIX)
base::FileHandleMappingVector unused; base::FileHandleMappingVector unused;
platform_server_channel->GetDataNeededToPassClientChannelToChildProcess( platform_channel_pair_->PrepareToPassClientChannelToChildProcess(
&command_line, &unused); &command_line, &unused);
#endif #endif
return command_line; return command_line;
...@@ -100,16 +101,16 @@ void MultiprocessTestBase::ChildSetup() { ...@@ -100,16 +101,16 @@ void MultiprocessTestBase::ChildSetup() {
CHECK(CommandLine::InitializedForCurrentProcess()); CHECK(CommandLine::InitializedForCurrentProcess());
// TODO(vtl): Not implemented on Windows yet. // TODO(vtl): Not implemented on Windows yet.
#if defined(OS_POSIX) #if defined(OS_POSIX)
platform_client_channel = client_platform_channel =
system::PlatformClientChannel::CreateFromParentProcess( system::PlatformChannelPair::CreateClientChannelFromParentProcess(
*CommandLine::ForCurrentProcess()); *CommandLine::ForCurrentProcess());
CHECK(platform_client_channel.get()); CHECK(client_platform_channel.get());
#endif #endif
} }
// static // static
scoped_ptr<system::PlatformClientChannel> scoped_ptr<system::PlatformChannel>
MultiprocessTestBase::platform_client_channel; MultiprocessTestBase::client_platform_channel;
} // namespace test } // namespace test
} // namespace mojo } // namespace mojo
...@@ -40,15 +40,17 @@ class MultiprocessTestBase : public base::MultiProcessTest { ...@@ -40,15 +40,17 @@ class MultiprocessTestBase : public base::MultiProcessTest {
static void ChildSetup(); static void ChildSetup();
// For use in the main process: // For use in the main process:
scoped_ptr<system::PlatformServerChannel> platform_server_channel; scoped_ptr<system::PlatformChannel> server_platform_channel;
// For use (and only valid) in the child process: // For use (and only valid) in the child process:
static scoped_ptr<system::PlatformClientChannel> platform_client_channel; static scoped_ptr<system::PlatformChannel> client_platform_channel;
private: private:
virtual CommandLine MakeCmdLine(const std::string& procname, virtual CommandLine MakeCmdLine(const std::string& procname,
bool debug_on_start) OVERRIDE; bool debug_on_start) OVERRIDE;
scoped_ptr<system::PlatformChannelPair> platform_channel_pair_;
// Valid after |StartChild()| and before |WaitForChildShutdown()|. // Valid after |StartChild()| and before |WaitForChildShutdown()|.
base::ProcessHandle test_child_handle_; base::ProcessHandle test_child_handle_;
......
...@@ -24,8 +24,8 @@ class MultiprocessTestBaseTest : public test::MultiprocessTestBase { ...@@ -24,8 +24,8 @@ class MultiprocessTestBaseTest : public test::MultiprocessTestBase {
TEST_F(MultiprocessTestBaseTest, RunChild) { TEST_F(MultiprocessTestBaseTest, RunChild) {
// TODO(vtl): Not implemented on Windows yet. // TODO(vtl): Not implemented on Windows yet.
#if defined(OS_POSIX) #if defined(OS_POSIX)
EXPECT_TRUE(platform_server_channel.get()); EXPECT_TRUE(server_platform_channel.get());
EXPECT_TRUE(platform_server_channel->is_valid()); EXPECT_TRUE(server_platform_channel->is_valid());
#endif #endif
StartChild("RunChild"); StartChild("RunChild");
EXPECT_EQ(123, WaitForChildShutdown()); EXPECT_EQ(123, WaitForChildShutdown());
...@@ -34,8 +34,8 @@ TEST_F(MultiprocessTestBaseTest, RunChild) { ...@@ -34,8 +34,8 @@ TEST_F(MultiprocessTestBaseTest, RunChild) {
MOJO_MULTIPROCESS_TEST_CHILD_MAIN(RunChild) { MOJO_MULTIPROCESS_TEST_CHILD_MAIN(RunChild) {
// TODO(vtl): Not implemented on Windows yet. // TODO(vtl): Not implemented on Windows yet.
#if defined(OS_POSIX) #if defined(OS_POSIX)
CHECK(MultiprocessTestBaseTest::platform_client_channel.get()); CHECK(MultiprocessTestBaseTest::client_platform_channel.get());
CHECK(MultiprocessTestBaseTest::platform_client_channel->is_valid()); CHECK(MultiprocessTestBaseTest::client_platform_channel->is_valid());
#endif #endif
return 123; return 123;
} }
...@@ -50,14 +50,14 @@ TEST_F(MultiprocessTestBaseTest, TestChildMainNotFound) { ...@@ -50,14 +50,14 @@ TEST_F(MultiprocessTestBaseTest, TestChildMainNotFound) {
#if defined(OS_POSIX) #if defined(OS_POSIX)
TEST_F(MultiprocessTestBaseTest, PassedChannelPosix) { TEST_F(MultiprocessTestBaseTest, PassedChannelPosix) {
EXPECT_TRUE(platform_server_channel.get()); EXPECT_TRUE(server_platform_channel.get());
EXPECT_TRUE(platform_server_channel->is_valid()); EXPECT_TRUE(server_platform_channel->is_valid());
StartChild("PassedChannelPosix"); StartChild("PassedChannelPosix");
// Take ownership of the FD. // Take ownership of the FD.
mojo::system::PlatformChannelHandle channel = mojo::system::PlatformChannelHandle channel =
platform_server_channel->PassHandle(); server_platform_channel->PassHandle();
platform_server_channel.reset(); server_platform_channel.reset();
int fd = channel.fd; int fd = channel.fd;
// The FD should be non-blocking. Check this. // The FD should be non-blocking. Check this.
...@@ -81,13 +81,13 @@ TEST_F(MultiprocessTestBaseTest, PassedChannelPosix) { ...@@ -81,13 +81,13 @@ TEST_F(MultiprocessTestBaseTest, PassedChannelPosix) {
} }
MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannelPosix) { MOJO_MULTIPROCESS_TEST_CHILD_MAIN(PassedChannelPosix) {
CHECK(MultiprocessTestBaseTest::platform_client_channel.get()); CHECK(MultiprocessTestBaseTest::client_platform_channel.get());
CHECK(MultiprocessTestBaseTest::platform_client_channel->is_valid()); CHECK(MultiprocessTestBaseTest::client_platform_channel->is_valid());
// Take ownership of the FD. // Take ownership of the FD.
mojo::system::PlatformChannelHandle channel = mojo::system::PlatformChannelHandle channel =
MultiprocessTestBaseTest::platform_client_channel->PassHandle(); MultiprocessTestBaseTest::client_platform_channel->PassHandle();
MultiprocessTestBaseTest::platform_client_channel.reset(); MultiprocessTestBaseTest::client_platform_channel.reset();
int fd = channel.fd; int fd = channel.fd;
// The FD should still be non-blocking. Check this. // The FD should still be non-blocking. Check this.
......
...@@ -122,7 +122,7 @@ class MultiprocessMessagePipeTest : public mojo::test::MultiprocessTestBase { ...@@ -122,7 +122,7 @@ class MultiprocessMessagePipeTest : public mojo::test::MultiprocessTestBase {
} }
void Init(scoped_refptr<MessagePipe> mp) { void Init(scoped_refptr<MessagePipe> mp) {
io_thread_wrapper_.Init(platform_server_channel.get(), mp); io_thread_wrapper_.Init(server_platform_channel.get(), mp);
} }
private: private:
...@@ -152,14 +152,14 @@ MojoResult WaitIfNecessary(scoped_refptr<MessagePipe> mp, MojoWaitFlags flags) { ...@@ -152,14 +152,14 @@ MojoResult WaitIfNecessary(scoped_refptr<MessagePipe> mp, MojoWaitFlags flags) {
// not including any "quitquitquit" message, modulo 100. // not including any "quitquitquit" message, modulo 100.
MOJO_MULTIPROCESS_TEST_CHILD_MAIN(EchoEcho) { MOJO_MULTIPROCESS_TEST_CHILD_MAIN(EchoEcho) {
IOThreadWrapper io_thread_wrapper; IOThreadWrapper io_thread_wrapper;
PlatformClientChannel* const platform_client_channel = PlatformChannel* const client_platform_channel =
MultiprocessMessagePipeTest::platform_client_channel.get(); MultiprocessMessagePipeTest::client_platform_channel.get();
CHECK(platform_client_channel); CHECK(client_platform_channel);
CHECK(platform_client_channel->is_valid()); CHECK(client_platform_channel->is_valid());
scoped_refptr<MessagePipe> mp(new MessagePipe( scoped_refptr<MessagePipe> mp(new MessagePipe(
scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()), scoped_ptr<MessagePipeEndpoint>(new LocalMessagePipeEndpoint()),
scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint()))); scoped_ptr<MessagePipeEndpoint>(new ProxyMessagePipeEndpoint())));
io_thread_wrapper.Init(platform_client_channel, mp); io_thread_wrapper.Init(client_platform_channel, mp);
const std::string quitquitquit("quitquitquit"); const std::string quitquitquit("quitquitquit");
int rv = 0; int rv = 0;
......
...@@ -13,6 +13,15 @@ PlatformChannel::~PlatformChannel() { ...@@ -13,6 +13,15 @@ PlatformChannel::~PlatformChannel() {
handle_.CloseIfNecessary(); handle_.CloseIfNecessary();
} }
// static
scoped_ptr<PlatformChannel> PlatformChannel::CreateFromHandle(
const PlatformChannelHandle& handle) {
DCHECK(handle.is_valid());
scoped_ptr<PlatformChannel> rv(new PlatformChannel());
*rv->mutable_handle() = handle;
return rv.Pass();
}
PlatformChannelHandle PlatformChannel::PassHandle() { PlatformChannelHandle PlatformChannel::PassHandle() {
DCHECK(is_valid()); DCHECK(is_valid());
PlatformChannelHandle rv = handle_; PlatformChannelHandle rv = handle_;
...@@ -23,18 +32,34 @@ PlatformChannelHandle PlatformChannel::PassHandle() { ...@@ -23,18 +32,34 @@ PlatformChannelHandle PlatformChannel::PassHandle() {
PlatformChannel::PlatformChannel() { PlatformChannel::PlatformChannel() {
} }
PlatformServerChannel::PlatformServerChannel(const std::string& name) // -----------------------------------------------------------------------------
: name_(name) {
DCHECK(!name_.empty()); PlatformChannelPair::~PlatformChannelPair() {
server_handle_.CloseIfNecessary();
client_handle_.CloseIfNecessary();
} }
// Static factory method. scoped_ptr<PlatformChannel> PlatformChannelPair::CreateServerChannel() {
// static if (!server_handle_.is_valid()) {
scoped_ptr<PlatformClientChannel> PlatformClientChannel::CreateFromHandle( LOG(WARNING) << "Server handle invalid";
const PlatformChannelHandle& handle) { return scoped_ptr<PlatformChannel>();
DCHECK(handle.is_valid()); }
scoped_ptr<PlatformClientChannel> rv(new PlatformClientChannel());
*rv->mutable_handle() = handle; scoped_ptr<PlatformChannel> rv =
PlatformChannel::CreateFromHandle(server_handle_);
server_handle_ = PlatformChannelHandle();
return rv.Pass();
}
scoped_ptr<PlatformChannel> PlatformChannelPair::CreateClientChannel() {
if (!client_handle_.is_valid()) {
LOG(WARNING) << "Client handle invalid";
return scoped_ptr<PlatformChannel>();
}
scoped_ptr<PlatformChannel> rv =
PlatformChannel::CreateFromHandle(client_handle_);
client_handle_ = PlatformChannelHandle();
return rv.Pass(); return rv.Pass();
} }
......
...@@ -5,9 +5,6 @@ ...@@ -5,9 +5,6 @@
#ifndef MOJO_SYSTEM_PLATFORM_CHANNEL_H_ #ifndef MOJO_SYSTEM_PLATFORM_CHANNEL_H_
#define MOJO_SYSTEM_PLATFORM_CHANNEL_H_ #define MOJO_SYSTEM_PLATFORM_CHANNEL_H_
#include <string>
#include <utility>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/process/launch.h" #include "base/process/launch.h"
...@@ -23,6 +20,11 @@ class MOJO_SYSTEM_IMPL_EXPORT PlatformChannel { ...@@ -23,6 +20,11 @@ class MOJO_SYSTEM_IMPL_EXPORT PlatformChannel {
public: public:
virtual ~PlatformChannel(); virtual ~PlatformChannel();
// Creates a channel if you already have the underlying handle for it, taking
// ownership of |handle|.
static scoped_ptr<PlatformChannel> CreateFromHandle(
const PlatformChannelHandle& handle);
// Returns the channel's handle, passing ownership. // Returns the channel's handle, passing ownership.
PlatformChannelHandle PassHandle(); PlatformChannelHandle PassHandle();
...@@ -39,71 +41,57 @@ class MOJO_SYSTEM_IMPL_EXPORT PlatformChannel { ...@@ -39,71 +41,57 @@ class MOJO_SYSTEM_IMPL_EXPORT PlatformChannel {
DISALLOW_COPY_AND_ASSIGN(PlatformChannel); DISALLOW_COPY_AND_ASSIGN(PlatformChannel);
}; };
class PlatformClientChannel; // This is used to create a pair of connected |PlatformChannel|s. The resulting
// channels can then be used in the same process (e.g., in tests) or between
// A server channel has an "implicit" client channel created with it. This may // processes. (The "server" channel is the one that will be used in the process
// be a real channel (in the case of POSIX, in which case there's an actual FD // that created the pair, whereas the "client" channel is the one that will be
// for it) or fake. // used in a different process.)
// - That client channel may then be used in-process (e.g., for single process //
// tests) by getting a |PlatformClientChannel| using |CreateClientChannel()|. // This class provides facilities for passing the client channel to a child
// - Or it may be "passed" to a new child process using // process. The parent should call |PrepareToPassClientChannelToChildProcess()|
// |GetDataNeededToPassClientChannelToChildProcess()|, etc. (see below). The // to get the data needed to do this, spawn the child using that data, and then
// child process would then get a |PlatformClientChannel| by using // call |ChildProcessLaunched()|. Note that on Windows this facility (will) only
// |PlatformClientChannel::CreateFromParentProcess()|. // work on Vista and later (TODO(vtl)).
// - In both these cases, "ownership" of the client channel is transferred (to //
// the |PlatformClientChannel| or the child process). // Note: |PlatformChannelPair()|, |CreateClientChannelFromParentProcess()|,
// TODO(vtl): Add ways of passing it to other existing processes. // |PrepareToPassClientChannelToChildProcess()|, and |ChildProcessLaunched()|
class MOJO_SYSTEM_IMPL_EXPORT PlatformServerChannel : public PlatformChannel { // have platform-specific implementations.
class MOJO_SYSTEM_IMPL_EXPORT PlatformChannelPair {
public: public:
virtual ~PlatformServerChannel() {} PlatformChannelPair();
~PlatformChannelPair();
static scoped_ptr<PlatformServerChannel> Create(const std::string& name);
// This transfers ownership of the server channel to the caller. Returns null
// For in-process use, from a server channel you can make a corresponding // on failure.
// client channel. scoped_ptr<PlatformChannel> CreateServerChannel();
virtual scoped_ptr<PlatformClientChannel> CreateClientChannel() = 0;
// For in-process use (e.g., in tests). This transfers ownership of the client
// channel to the caller. Returns null on failure.
scoped_ptr<PlatformChannel> CreateClientChannel();
// To be called in the child process, after the parent process called
// |PrepareToPassClientChannelToChildProcess()| and launched the child (using
// the provided data), to create a client channel connected to the server
// channel (in the parent process). Returns null on failure.
static scoped_ptr<PlatformChannel> CreateClientChannelFromParentProcess(
const CommandLine& command_line);
// Prepares to pass the client channel to a new child process, to be launched // Prepares to pass the client channel to a new child process, to be launched
// using |LaunchProcess()| (from base/launch.h). Modifies |*command_line| and // using |LaunchProcess()| (from base/launch.h). Modifies |*command_line| and
// |*file_handle_mapping| as needed. (|file_handle_mapping| may be null on // |*file_handle_mapping| as needed. (|file_handle_mapping| may be null on
// platforms that don't need it, like Windows.) // platforms that don't need it, like Windows.)
virtual void GetDataNeededToPassClientChannelToChildProcess( void PrepareToPassClientChannelToChildProcess(
CommandLine* command_line, CommandLine* command_line,
base::FileHandleMappingVector* file_handle_mapping) const = 0; base::FileHandleMappingVector* file_handle_mapping) const;
// To be called once the child process has been successfully launched, to do // To be called once the child process has been successfully launched, to do
// any cleanup necessary. // any cleanup necessary.
virtual void ChildProcessLaunched() = 0; void ChildProcessLaunched();
const std::string& name() const { return name_; }
protected:
explicit PlatformServerChannel(const std::string& name);
private:
const std::string name_;
DISALLOW_COPY_AND_ASSIGN(PlatformServerChannel);
};
class MOJO_SYSTEM_IMPL_EXPORT PlatformClientChannel : public PlatformChannel {
public:
virtual ~PlatformClientChannel() {}
// Creates a client channel if you already have the underlying handle for it.
// Note: This takes ownership of |handle|.
static scoped_ptr<PlatformClientChannel> CreateFromHandle(
const PlatformChannelHandle& handle);
// To be called to get a client channel passed from the parent process, using
// |PlatformServerChannel::GetDataNeededToPassClientChannelToChildProcess()|,
// etc. Returns null on failure.
static scoped_ptr<PlatformClientChannel> CreateFromParentProcess(
const CommandLine& command_line);
private: private:
PlatformClientChannel() {} PlatformChannelHandle server_handle_;
PlatformChannelHandle client_handle_;
DISALLOW_COPY_AND_ASSIGN(PlatformClientChannel); DISALLOW_COPY_AND_ASSIGN(PlatformChannelPair);
}; };
} // namespace system } // namespace system
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include <unistd.h> #include <unistd.h>
#include "base/command_line.h" #include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/posix/global_descriptors.h" #include "base/posix/global_descriptors.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
...@@ -32,58 +31,40 @@ bool IsTargetDescriptorUsed( ...@@ -32,58 +31,40 @@ bool IsTargetDescriptorUsed(
return false; return false;
} }
class PlatformServerChannelPosix : public PlatformServerChannel { } // namespace
public:
PlatformServerChannelPosix(const std::string& name);
virtual ~PlatformServerChannelPosix();
// |PlatformServerChannel| implementation:
virtual scoped_ptr<PlatformClientChannel> CreateClientChannel() OVERRIDE;
virtual void GetDataNeededToPassClientChannelToChildProcess(
CommandLine* command_line,
base::FileHandleMappingVector* file_handle_mapping) const OVERRIDE;
virtual void ChildProcessLaunched() OVERRIDE;
private:
PlatformChannelHandle client_handle_;
DISALLOW_COPY_AND_ASSIGN(PlatformServerChannelPosix);
};
PlatformServerChannelPosix::PlatformServerChannelPosix( PlatformChannelPair::PlatformChannelPair() {
const std::string& name)
: PlatformServerChannel(name) {
// Create the Unix domain socket and set the ends to nonblocking. // Create the Unix domain socket and set the ends to nonblocking.
int fds[2]; int fds[2];
// TODO(vtl): Maybe fail gracefully if |socketpair()| fails.
PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
PCHECK(fcntl(fds[0], F_SETFL, O_NONBLOCK) == 0); PCHECK(fcntl(fds[0], F_SETFL, O_NONBLOCK) == 0);
PCHECK(fcntl(fds[1], F_SETFL, O_NONBLOCK) == 0); PCHECK(fcntl(fds[1], F_SETFL, O_NONBLOCK) == 0);
mutable_handle()->fd = fds[0]; server_handle_.fd = fds[0];
DCHECK(is_valid()); DCHECK(server_handle_.is_valid());
client_handle_.fd = fds[1]; client_handle_.fd = fds[1];
DCHECK(client_handle_.is_valid()); DCHECK(client_handle_.is_valid());
} }
PlatformServerChannelPosix::~PlatformServerChannelPosix() { // static
client_handle_.CloseIfNecessary(); scoped_ptr<PlatformChannel>
} PlatformChannelPair::CreateClientChannelFromParentProcess(
const CommandLine& command_line) {
scoped_ptr<PlatformClientChannel> std::string client_fd_string =
PlatformServerChannelPosix::CreateClientChannel() { command_line.GetSwitchValueASCII(kMojoChannelDescriptorSwitch);
if (!client_handle_.is_valid()) { int client_fd = -1;
NOTREACHED(); if (client_fd_string.empty() ||
return scoped_ptr<PlatformClientChannel>(); !base::StringToInt(client_fd_string, &client_fd) ||
client_fd < base::GlobalDescriptors::kBaseDescriptor) {
LOG(ERROR) << "Missing or invalid --" << kMojoChannelDescriptorSwitch;
return scoped_ptr<PlatformChannel>();
} }
scoped_ptr<PlatformClientChannel> rv = return PlatformChannel::CreateFromHandle(PlatformChannelHandle(client_fd));
PlatformClientChannel::CreateFromHandle(client_handle_);
DCHECK(rv->is_valid());
client_handle_ = PlatformChannelHandle();
return rv.Pass();
} }
void PlatformServerChannelPosix::GetDataNeededToPassClientChannelToChildProcess( void PlatformChannelPair::PrepareToPassClientChannelToChildProcess(
CommandLine* command_line, CommandLine* command_line,
base::FileHandleMappingVector* file_handle_mapping) const { base::FileHandleMappingVector* file_handle_mapping) const {
DCHECK(command_line); DCHECK(command_line);
...@@ -116,42 +97,10 @@ void PlatformServerChannelPosix::GetDataNeededToPassClientChannelToChildProcess( ...@@ -116,42 +97,10 @@ void PlatformServerChannelPosix::GetDataNeededToPassClientChannelToChildProcess(
base::IntToString(target_fd)); base::IntToString(target_fd));
} }
void PlatformServerChannelPosix::ChildProcessLaunched() { void PlatformChannelPair::ChildProcessLaunched() {
DCHECK(client_handle_.is_valid()); DCHECK(client_handle_.is_valid());
client_handle_.CloseIfNecessary(); client_handle_.CloseIfNecessary();
} }
} // namespace
// -----------------------------------------------------------------------------
// Static factory method declared in platform_channel.h.
// static
scoped_ptr<PlatformServerChannel> PlatformServerChannel::Create(
const std::string& name) {
return scoped_ptr<PlatformServerChannel>(
new PlatformServerChannelPosix(name));
}
// -----------------------------------------------------------------------------
// Static factory method declared in platform_channel.h.
// static
scoped_ptr<PlatformClientChannel>
PlatformClientChannel::CreateFromParentProcess(
const CommandLine& command_line) {
std::string client_fd_string =
command_line.GetSwitchValueASCII(kMojoChannelDescriptorSwitch);
int client_fd = -1;
if (client_fd_string.empty() ||
!base::StringToInt(client_fd_string, &client_fd) ||
client_fd < base::GlobalDescriptors::kBaseDescriptor) {
LOG(ERROR) << "Missing or invalid --" << kMojoChannelDescriptorSwitch;
return scoped_ptr<PlatformClientChannel>();
}
return CreateFromHandle(PlatformChannelHandle(client_fd));
}
} // namespace system } // namespace system
} // namespace mojo } // namespace mojo
...@@ -77,12 +77,13 @@ class RawChannelPosixTest : public testing::Test { ...@@ -77,12 +77,13 @@ class RawChannelPosixTest : public testing::Test {
io_thread_.StartWithOptions( io_thread_.StartWithOptions(
base::Thread::Options(base::MessageLoop::TYPE_IO, 0)); base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
scoped_ptr<PlatformServerChannel> server_channel( PlatformChannelPair channel_pair;
PlatformServerChannel::Create("channel")); scoped_ptr<PlatformChannel> server_channel(
channel_pair.CreateServerChannel());
CHECK(server_channel.get()); CHECK(server_channel.get());
CHECK(server_channel->is_valid()); CHECK(server_channel->is_valid());
scoped_ptr<PlatformClientChannel> client_channel( scoped_ptr<PlatformChannel> client_channel(
server_channel->CreateClientChannel()); channel_pair.CreateClientChannel());
CHECK(client_channel.get()); CHECK(client_channel.get());
CHECK(client_channel->is_valid()); CHECK(client_channel->is_valid());
......
...@@ -91,17 +91,13 @@ class RemoteMessagePipeTest : public testing::Test { ...@@ -91,17 +91,13 @@ class RemoteMessagePipeTest : public testing::Test {
void SetUpOnIOThread() { void SetUpOnIOThread() {
CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop()); CHECK_EQ(base::MessageLoop::current(), io_thread_message_loop());
scoped_ptr<PlatformServerChannel> server_channel( PlatformChannelPair channel_pair;
PlatformServerChannel::Create("channel")); platform_channels_[0] = channel_pair.CreateServerChannel();
CHECK(server_channel.get()); CHECK(platform_channels_[0].get());
CHECK(server_channel->is_valid()); CHECK(platform_channels_[0]->is_valid());
scoped_ptr<PlatformClientChannel> client_channel( platform_channels_[1] = channel_pair.CreateClientChannel();
server_channel->CreateClientChannel()); CHECK(platform_channels_[1].get());
CHECK(client_channel.get()); CHECK(platform_channels_[1]->is_valid());
CHECK(client_channel->is_valid());
platform_channels_[0] = server_channel.PassAs<PlatformChannel>();
platform_channels_[1] = client_channel.PassAs<PlatformChannel>();
} }
void CreateAndInitChannel(unsigned channel_index) { void CreateAndInitChannel(unsigned channel_index) {
......
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