Chromium Code Reviews| Index: mojo/edk/system/multiprocess_message_pipe_unittest.cc |
| diff --git a/mojo/edk/system/multiprocess_message_pipe_unittest.cc b/mojo/edk/system/multiprocess_message_pipe_unittest.cc |
| index 124daec9a8b0c6703bf712c037bd304d4a472f7d..03f89987295c2eb747cf15f91904d18fe83aa3d8 100644 |
| --- a/mojo/edk/system/multiprocess_message_pipe_unittest.cc |
| +++ b/mojo/edk/system/multiprocess_message_pipe_unittest.cc |
| @@ -18,6 +18,8 @@ |
| #include "base/files/scoped_file.h" |
| #include "base/files/scoped_temp_dir.h" |
| #include "base/logging.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "base/run_loop.h" |
| #include "base/strings/string_split.h" |
| #include "build/build_config.h" |
| #include "mojo/edk/embedder/platform_channel_pair.h" |
| @@ -29,6 +31,7 @@ |
| #include "mojo/public/c/system/buffer.h" |
| #include "mojo/public/c/system/functions.h" |
| #include "mojo/public/c/system/types.h" |
| +#include "mojo/public/cpp/system/watcher.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| @@ -1294,6 +1297,75 @@ TEST_F(MultiprocessMessagePipeTest, BootstrapMessagePipeAsync) { |
| END_CHILD() |
| } |
| +DEFINE_TEST_CLIENT_TEST_WITH_PIPE(MessagePipeStatusChangeInTransitClient, |
| + MultiprocessMessagePipeTest, parent) { |
| + // This test verifies that peer closure is detectable through various |
| + // mechanisms when it races with handle transfer. |
| + MojoHandle handles[4]; |
| + EXPECT_EQ("o_O", ReadMessageWithHandles(parent, handles, 4)); |
| + MojoHandle b = handles[0]; |
|
yzshen1
2016/08/19 22:20:05
optional, nit: it seems a little easier to read if
Ken Rockot(use gerrit already)
2016/08/19 22:28:00
Done
|
| + MojoHandle d = handles[1]; |
| + MojoHandle f = handles[2]; |
| + MojoHandle h = handles[3]; |
| + |
| + // Wait on handle |b| using MojoWait. |
| + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(b, MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
| + MOJO_DEADLINE_INDEFINITE, nullptr)); |
| + |
| + base::MessageLoop message_loop; |
| + |
| + // Wait on handle |d| using a Watcher. |
| + { |
| + base::RunLoop run_loop; |
| + Watcher watcher; |
| + watcher.Start(Handle(d), MOJO_HANDLE_SIGNAL_PEER_CLOSED, |
| + base::Bind([] (base::RunLoop* loop, MojoResult result) { |
| + EXPECT_EQ(MOJO_RESULT_OK, result); |
| + loop->Quit(); |
| + }, &run_loop)); |
| + run_loop.Run(); |
| + } |
| + |
| + // Wait on handle |f| by polling with MojoReadMessage. |
| + MojoResult result; |
| + do { |
| + result = MojoReadMessage(f, nullptr, nullptr, nullptr, nullptr, |
| + MOJO_READ_MESSAGE_FLAG_NONE); |
| + } while (result == MOJO_RESULT_SHOULD_WAIT); |
| + EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| + |
| + // Wait on handle |h| by polling with MojoWriteMessage. |
| + do { |
| + result = MojoWriteMessage(h, nullptr, 0, nullptr, 0, |
| + MOJO_WRITE_MESSAGE_FLAG_NONE); |
| + } while (result == MOJO_RESULT_OK); |
| + EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| + |
| + CloseHandle(b); |
| + CloseHandle(d); |
| + CloseHandle(f); |
| + CloseHandle(h); |
| +} |
| + |
| +TEST_F(MultiprocessMessagePipeTest, MessagePipeStatusChangeInTransit) { |
| + MojoHandle a, b, c, d, e, f, g, h; |
| + CreateMessagePipe(&a, &b); |
| + CreateMessagePipe(&c, &d); |
| + CreateMessagePipe(&e, &f); |
| + CreateMessagePipe(&g, &h); |
| + |
| + RUN_CHILD_ON_PIPE(MessagePipeStatusChangeInTransitClient, child) |
| + MojoHandle handles[] = { b, d, f, h }; |
| + |
| + // Send 4 handles and let their transfer race with their peers' closure. |
| + WriteMessageWithHandles(child, "o_O", handles, 4); |
| + CloseHandle(a); |
| + CloseHandle(c); |
| + CloseHandle(e); |
| + CloseHandle(g); |
| + END_CHILD() |
| +} |
| + |
| DEFINE_TEST_CLIENT_TEST_WITH_PIPE(BadMessageClient, MultiprocessMessagePipeTest, |
| parent) { |
| MojoHandle pipe; |