| Index: mojo/edk/system/remote_message_pipe_unittest.cc
|
| diff --git a/mojo/edk/system/remote_message_pipe_unittest.cc b/mojo/edk/system/remote_message_pipe_unittest.cc
|
| index f676c7f3d94aa43e42859226b0f982698dbfa1ca..d3a95dfe5c9256f73007c231fbe9cac060d1f4e9 100644
|
| --- a/mojo/edk/system/remote_message_pipe_unittest.cc
|
| +++ b/mojo/edk/system/remote_message_pipe_unittest.cc
|
| @@ -778,6 +778,158 @@ TEST_F(RemoteMessagePipeTest, HandlePassing) {
|
| local_mp->Close(1);
|
| }
|
|
|
| +TEST_F(RemoteMessagePipeTest, HandlePassingHalfClosed) {
|
| + static const char kHello[] = "hello";
|
| + static const char kWorld[] = "world!";
|
| + Waiter waiter;
|
| + HandleSignalsState hss;
|
| + uint32_t context = 0;
|
| +
|
| + // We'll try to pass this dispatcher.
|
| + scoped_refptr<MessagePipeDispatcher> dispatcher(
|
| + new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions));
|
| + scoped_refptr<MessagePipe> local_mp(MessagePipe::CreateLocalLocal());
|
| + dispatcher->Init(local_mp, 0);
|
| +
|
| + hss = local_mp->GetHandleSignalsState(0);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
|
| + hss.satisfiable_signals);
|
| + // Write to the other end (|local_mp|, port 1), and then close it.
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + local_mp->WriteMessage(1,
|
| + UserPointer<const void>(kHello),
|
| + sizeof(kHello),
|
| + nullptr,
|
| + MOJO_WRITE_MESSAGE_FLAG_NONE));
|
| + hss = local_mp->GetHandleSignalsState(0);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
|
| + hss.satisfied_signals);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
|
| + hss.satisfiable_signals);
|
| + // Then the second message....
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + local_mp->WriteMessage(1,
|
| + UserPointer<const void>(kWorld),
|
| + sizeof(kWorld),
|
| + nullptr,
|
| + MOJO_WRITE_MESSAGE_FLAG_NONE));
|
| + hss = local_mp->GetHandleSignalsState(0);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
|
| + hss.satisfied_signals);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
|
| + hss.satisfiable_signals);
|
| + // Then close it.
|
| + local_mp->Close(1);
|
| +
|
| + scoped_refptr<ChannelEndpoint> ep0;
|
| + scoped_refptr<MessagePipe> mp0(MessagePipe::CreateLocalProxy(&ep0));
|
| + scoped_refptr<ChannelEndpoint> ep1;
|
| + scoped_refptr<MessagePipe> mp1(MessagePipe::CreateProxyLocal(&ep1));
|
| + BootstrapChannelEndpoints(ep0, ep1);
|
| +
|
| + // Prepare to wait on MP 1, port 1. (Add the waiter now. Otherwise, if we do
|
| + // it later, it might already be readable.)
|
| + waiter.Init();
|
| + ASSERT_EQ(
|
| + MOJO_RESULT_OK,
|
| + mp1->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 123, nullptr));
|
| +
|
| + // Write to MP 0, port 0.
|
| + {
|
| + DispatcherTransport transport(
|
| + test::DispatcherTryStartTransport(dispatcher.get()));
|
| + EXPECT_TRUE(transport.is_valid());
|
| +
|
| + std::vector<DispatcherTransport> transports;
|
| + transports.push_back(transport);
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + mp0->WriteMessage(0,
|
| + UserPointer<const void>(kHello),
|
| + sizeof(kHello),
|
| + &transports,
|
| + MOJO_WRITE_MESSAGE_FLAG_NONE));
|
| + transport.End();
|
| +
|
| + // |dispatcher| should have been closed. This is |DCHECK()|ed when the
|
| + // |dispatcher| is destroyed.
|
| + EXPECT_TRUE(dispatcher->HasOneRef());
|
| + dispatcher = nullptr;
|
| + }
|
| +
|
| + // Wait.
|
| + EXPECT_EQ(MOJO_RESULT_OK, waiter.Wait(MOJO_DEADLINE_INDEFINITE, &context));
|
| + EXPECT_EQ(123u, context);
|
| + hss = HandleSignalsState();
|
| + mp1->RemoveWaiter(1, &waiter, &hss);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
|
| + hss.satisfied_signals);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
|
| + hss.satisfiable_signals);
|
| +
|
| + // Read from MP 1, port 1.
|
| + char read_buffer[100] = {0};
|
| + uint32_t read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
|
| + DispatcherVector read_dispatchers;
|
| + uint32_t read_num_dispatchers = 10; // Maximum to get.
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + mp1->ReadMessage(1,
|
| + UserPointer<void>(read_buffer),
|
| + MakeUserPointer(&read_buffer_size),
|
| + &read_dispatchers,
|
| + &read_num_dispatchers,
|
| + MOJO_READ_MESSAGE_FLAG_NONE));
|
| + EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
|
| + EXPECT_STREQ(kHello, read_buffer);
|
| + EXPECT_EQ(1u, read_dispatchers.size());
|
| + EXPECT_EQ(1u, read_num_dispatchers);
|
| + ASSERT_TRUE(read_dispatchers[0].get());
|
| + EXPECT_TRUE(read_dispatchers[0]->HasOneRef());
|
| +
|
| + EXPECT_EQ(Dispatcher::kTypeMessagePipe, read_dispatchers[0]->GetType());
|
| + dispatcher = static_cast<MessagePipeDispatcher*>(read_dispatchers[0].get());
|
| +
|
| + // |dispatcher| should already be readable and not writable.
|
| + hss = dispatcher->GetHandleSignalsState();
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
|
| + // So read from it.
|
| + memset(read_buffer, 0, sizeof(read_buffer));
|
| + read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + dispatcher->ReadMessage(UserPointer<void>(read_buffer),
|
| + MakeUserPointer(&read_buffer_size),
|
| + 0,
|
| + nullptr,
|
| + MOJO_READ_MESSAGE_FLAG_NONE));
|
| + EXPECT_EQ(sizeof(kHello), static_cast<size_t>(read_buffer_size));
|
| + EXPECT_STREQ(kHello, read_buffer);
|
| + // It should still be readable.
|
| + hss = dispatcher->GetHandleSignalsState();
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
|
| + // So read from it.
|
| + memset(read_buffer, 0, sizeof(read_buffer));
|
| + read_buffer_size = static_cast<uint32_t>(sizeof(read_buffer));
|
| + EXPECT_EQ(MOJO_RESULT_OK,
|
| + dispatcher->ReadMessage(UserPointer<void>(read_buffer),
|
| + MakeUserPointer(&read_buffer_size),
|
| + 0,
|
| + nullptr,
|
| + MOJO_READ_MESSAGE_FLAG_NONE));
|
| + EXPECT_EQ(sizeof(kWorld), static_cast<size_t>(read_buffer_size));
|
| + EXPECT_STREQ(kWorld, read_buffer);
|
| + // Now it should no longer be readable.
|
| + hss = dispatcher->GetHandleSignalsState();
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, hss.satisfied_signals);
|
| + EXPECT_EQ(MOJO_HANDLE_SIGNAL_NONE, hss.satisfiable_signals);
|
| +
|
| + // Close everything that belongs to us.
|
| + mp0->Close(0);
|
| + mp1->Close(1);
|
| + EXPECT_EQ(MOJO_RESULT_OK, dispatcher->Close());
|
| +}
|
| +
|
| #if defined(OS_POSIX)
|
| #define MAYBE_SharedBufferPassing SharedBufferPassing
|
| #else
|
|
|