| 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..5b35a29177eade907ea6de6bdec7c5f3e988abc3 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,64 @@ 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));
|
| +
|
| + // Wait on handle 0 using MojoWait.
|
| + EXPECT_EQ(MOJO_RESULT_OK, MojoWait(handles[0], MOJO_HANDLE_SIGNAL_PEER_CLOSED,
|
| + MOJO_DEADLINE_INDEFINITE, nullptr));
|
| +
|
| + base::MessageLoop message_loop;
|
| +
|
| + // Wait on handle 1 using a Watcher.
|
| + {
|
| + base::RunLoop run_loop;
|
| + Watcher watcher;
|
| + watcher.Start(Handle(handles[1]), 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 2 by polling with MojoReadMessage.
|
| + MojoResult result;
|
| + do {
|
| + result = MojoReadMessage(handles[2], 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 3 by polling with MojoWriteMessage.
|
| + do {
|
| + result = MojoWriteMessage(handles[3], nullptr, 0, nullptr, 0,
|
| + MOJO_WRITE_MESSAGE_FLAG_NONE);
|
| + } while (result == MOJO_RESULT_OK);
|
| + EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
|
| +
|
| + for (size_t i = 0; i < 4; ++i)
|
| + CloseHandle(handles[i]);
|
| +}
|
| +
|
| +TEST_F(MultiprocessMessagePipeTest, MessagePipeStatusChangeInTransit) {
|
| + MojoHandle local_handles[4];
|
| + MojoHandle sent_handles[4];
|
| + for (size_t i = 0; i < 4; ++i)
|
| + CreateMessagePipe(&local_handles[i], &sent_handles[i]);
|
| +
|
| + RUN_CHILD_ON_PIPE(MessagePipeStatusChangeInTransitClient, child)
|
| + // Send 4 handles and let their transfer race with their peers' closure.
|
| + WriteMessageWithHandles(child, "o_O", sent_handles, 4);
|
| + for (size_t i = 0; i < 4; ++i)
|
| + CloseHandle(local_handles[i]);
|
| + END_CHILD()
|
| +}
|
| +
|
| DEFINE_TEST_CLIENT_TEST_WITH_PIPE(BadMessageClient, MultiprocessMessagePipeTest,
|
| parent) {
|
| MojoHandle pipe;
|
|
|