IPC::ChannelMojo: Introduce IPC::MojoBootstrap for Windows
ChannelMojo doesn't work on Windows with existing implementaion
and this CL fixes it.
On Windows, ChannelHandle isn't immediately usable: The handle has
to be activated through ConnectNamedPipe() windows API, which is done in
its own Connect() handlshaking phase. ChannelMojo didn't Connect()
underlying channel and took the ChannelHandle over so the handle
wasn't activated.
Instead of hijacking underlying ChannelHandle, this CL actually Connect()s
underlying channel, creates a pipe on the server side, send one side of the
pipe to the client process, and use the pipe for the MessagePipe
initialization.
These initialization task is encapsulated behind new MojoBootstrap class.
ChannelMojo creates MojoBootstrap class to get the PlatformHandle which
is already activated and usable.
BUG=377980
TEST=ipc_mojo_bootstrap_unittest.cc, ipc_channel_mojo_unittest.cc
[email protected], [email protected], [email protected]
Review URL: https://codereview.chromium.org/553283002
Cr-Commit-Position: refs/heads/master@{#296248}
diff --git a/ipc/ipc_test_base.cc b/ipc/ipc_test_base.cc
index 6abef0f14..ba4e711 100644
--- a/ipc/ipc_test_base.cc
+++ b/ipc/ipc_test_base.cc
@@ -52,8 +52,7 @@
}
void IPCTestBase::CreateChannel(IPC::Listener* listener) {
- CreateChannelFromChannelHandle(
- GetChannelName(test_client_name_), listener);
+ CreateChannelFromChannelHandle(GetTestChannelHandle(), listener);
}
bool IPCTestBase::ConnectChannel() {
@@ -90,8 +89,7 @@
CHECK(!channel_.get());
CHECK(!channel_proxy_.get());
channel_proxy_ = IPC::ChannelProxy::Create(
- CreateChannelFactory(GetChannelName(test_client_name_),
- ipc_task_runner.get()),
+ CreateChannelFactory(GetTestChannelHandle(), ipc_task_runner.get()),
listener,
ipc_task_runner);
}
@@ -101,29 +99,47 @@
channel_proxy_.reset();
}
+std::string IPCTestBase::GetTestMainName() const {
+ return test_client_name_ + "TestClientMain";
+}
+
+bool IPCTestBase::DidStartClient() {
+ DCHECK_NE(base::kNullProcessHandle, client_process_);
+ return client_process_ != base::kNullProcessHandle;
+}
+
+#if defined(OS_POSIX)
+
bool IPCTestBase::StartClient() {
- DCHECK(client_process_ == base::kNullProcessHandle);
+ return StartClientWithFD(channel_
+ ? channel_->GetClientFileDescriptor()
+ : channel_proxy_->GetClientFileDescriptor());
+}
- std::string test_main = test_client_name_ + "TestClientMain";
+bool IPCTestBase::StartClientWithFD(int ipcfd) {
+ DCHECK_EQ(client_process_, base::kNullProcessHandle);
-#if defined(OS_WIN)
- client_process_ = SpawnChild(test_main);
-#elif defined(OS_POSIX)
base::FileHandleMappingVector fds_to_map;
- const int ipcfd = channel_.get()
- ? channel_->GetClientFileDescriptor()
- : channel_proxy_->GetClientFileDescriptor();
if (ipcfd > -1)
fds_to_map.push_back(std::pair<int, int>(ipcfd,
kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor));
base::LaunchOptions options;
options.fds_to_remap = &fds_to_map;
- client_process_ = SpawnChildWithOptions(test_main, options);
-#endif
+ client_process_ = SpawnChildWithOptions(GetTestMainName(), options);
- return client_process_ != base::kNullProcessHandle;
+ return DidStartClient();
}
+#elif defined(OS_WIN)
+
+bool IPCTestBase::StartClient() {
+ DCHECK_EQ(client_process_, base::kNullProcessHandle);
+ client_process_ = SpawnChild(GetTestMainName());
+ return DidStartClient();
+}
+
+#endif
+
bool IPCTestBase::WaitForClientShutdown() {
DCHECK(client_process_ != base::kNullProcessHandle);
@@ -134,6 +150,10 @@
return rv;
}
+IPC::ChannelHandle IPCTestBase::GetTestChannelHandle() {
+ return GetChannelName(test_client_name_);
+}
+
scoped_refptr<base::TaskRunner> IPCTestBase::task_runner() {
return message_loop_->message_loop_proxy();
}