diff options
author | jam <jam@chromium.org> | 2015-10-26 12:15:33 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-10-26 19:16:15 +0000 |
commit | be81738d16b0e1dcb51f2f92fc10ac6d216d42a1 (patch) | |
tree | e0e885ff056158dbbf75408e7ebff48d66f0c0eb | |
parent | 615479bb713dd274decd8facfb2694fffe83a372 (diff) | |
download | chromium_src-be81738d16b0e1dcb51f2f92fc10ac6d216d42a1.zip chromium_src-be81738d16b0e1dcb51f2f92fc10ac6d216d42a1.tar.gz chromium_src-be81738d16b0e1dcb51f2f92fc10ac6d216d42a1.tar.bz2 |
Get the new Mojo EDK working on POSIX.
Some notes:
-in RawChannel, I'm passing FDs as ints instead of PlatformHandle to make it very clear that this is only used on POSIX
BUG=478251
Review URL: https://codereview.chromium.org/1417773004
Cr-Commit-Position: refs/heads/master@{#356092}
-rw-r--r-- | mojo/edk/embedder/embedder.cc | 3 | ||||
-rw-r--r-- | mojo/edk/embedder/embedder_unittest.cc | 2 | ||||
-rw-r--r-- | mojo/edk/embedder/platform_channel_pair_posix.cc | 14 | ||||
-rw-r--r-- | mojo/edk/embedder/platform_channel_utils_posix.cc | 12 | ||||
-rw-r--r-- | mojo/edk/embedder/platform_channel_utils_posix.h | 5 | ||||
-rw-r--r-- | mojo/edk/system/core.cc | 6 | ||||
-rw-r--r-- | mojo/edk/system/core_unittest.cc | 752 | ||||
-rw-r--r-- | mojo/edk/system/data_pipe_consumer_dispatcher.cc | 12 | ||||
-rw-r--r-- | mojo/edk/system/data_pipe_producer_dispatcher.cc | 8 | ||||
-rw-r--r-- | mojo/edk/system/data_pipe_unittest.cc | 2 | ||||
-rw-r--r-- | mojo/edk/system/dispatcher.h | 3 | ||||
-rw-r--r-- | mojo/edk/system/message_pipe_dispatcher.cc | 164 | ||||
-rw-r--r-- | mojo/edk/system/message_pipe_dispatcher.h | 12 | ||||
-rw-r--r-- | mojo/edk/system/raw_channel.cc | 17 | ||||
-rw-r--r-- | mojo/edk/system/raw_channel.h | 37 | ||||
-rw-r--r-- | mojo/edk/system/raw_channel_posix.cc | 104 | ||||
-rw-r--r-- | mojo/edk/system/raw_channel_win.cc | 10 | ||||
-rw-r--r-- | mojo/edk/system/transport_data.cc | 15 | ||||
-rw-r--r-- | mojo/edk/system/transport_data.h | 4 | ||||
-rw-r--r-- | mojo/runner/linux_sandbox.cc | 2 |
20 files changed, 706 insertions, 478 deletions
diff --git a/mojo/edk/embedder/embedder.cc b/mojo/edk/embedder/embedder.cc index 91f03d0..fe5202c 100644 --- a/mojo/edk/embedder/embedder.cc +++ b/mojo/edk/embedder/embedder.cc @@ -166,7 +166,8 @@ ScopedMessagePipeHandle CreateMessagePipe( ScopedMessagePipeHandle rv( MessagePipeHandle(internal::g_core->AddDispatcher(dispatcher))); CHECK(rv.is_valid()); - dispatcher->Init(platform_handle.Pass(), nullptr, 0, nullptr, 0); + dispatcher->Init(platform_handle.Pass(), nullptr, 0, nullptr, 0, nullptr, + nullptr); // TODO(vtl): The |.Pass()| below is only needed due to an MSVS bug; remove it // once that's fixed. return rv.Pass(); diff --git a/mojo/edk/embedder/embedder_unittest.cc b/mojo/edk/embedder/embedder_unittest.cc index bbc3f52..f53e440 100644 --- a/mojo/edk/embedder/embedder_unittest.cc +++ b/mojo/edk/embedder/embedder_unittest.cc @@ -126,7 +126,7 @@ TEST_F(EmbedderTest, SendReadableMessagePipe) { char read_buffer[20000] = {}; uint32_t num_bytes = static_cast<uint32_t>(sizeof(read_buffer)); MojoHandle ports[10]; - uint32_t num_ports; + uint32_t num_ports = arraysize(ports); ASSERT_EQ(MOJO_RESULT_OK, MojoReadMessage(client_mp, read_buffer, &num_bytes, &ports[0], &num_ports, MOJO_READ_MESSAGE_FLAG_NONE)); diff --git a/mojo/edk/embedder/platform_channel_pair_posix.cc b/mojo/edk/embedder/platform_channel_pair_posix.cc index 8cdac36..eaeac26 100644 --- a/mojo/edk/embedder/platform_channel_pair_posix.cc +++ b/mojo/edk/embedder/platform_channel_pair_posix.cc @@ -12,10 +12,15 @@ #include "base/command_line.h" #include "base/logging.h" #include "base/posix/global_descriptors.h" +#include "base/rand_util.h" #include "base/strings/string_number_conversions.h" #include "build/build_config.h" #include "mojo/edk/embedder/platform_handle.h" +#if !defined(SO_PEEK_OFF) +#define SO_PEEK_OFF 42 +#endif + namespace mojo { namespace edk { @@ -37,7 +42,16 @@ PlatformChannelPair::PlatformChannelPair() { // Create the Unix domain socket and set the ends to nonblocking. int fds[2]; // TODO(vtl): Maybe fail gracefully if |socketpair()| fails. + PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); + + // Store a common id in the SO_PEEK_OFF option (which we don't use since we + // don't peak) as a way of determining later if two sockets are connected to + // each other. + int identifier = base::RandInt(kint32min, kint32max); + setsockopt(fds[0], SOL_SOCKET, SO_PEEK_OFF, &identifier, sizeof(identifier)); + setsockopt(fds[1], SOL_SOCKET, SO_PEEK_OFF, &identifier, sizeof(identifier)); + PCHECK(fcntl(fds[0], F_SETFL, O_NONBLOCK) == 0); PCHECK(fcntl(fds[1], F_SETFL, O_NONBLOCK) == 0); diff --git a/mojo/edk/embedder/platform_channel_utils_posix.cc b/mojo/edk/embedder/platform_channel_utils_posix.cc index 4af45e82..c064139 100644 --- a/mojo/edk/embedder/platform_channel_utils_posix.cc +++ b/mojo/edk/embedder/platform_channel_utils_posix.cc @@ -12,6 +12,10 @@ #include "base/posix/eintr_wrapper.h" #include "build/build_config.h" +#if !defined(SO_PEEK_OFF) +#define SO_PEEK_OFF 42 +#endif + namespace mojo { namespace edk { @@ -155,10 +159,18 @@ ssize_t PlatformChannelRecvmsg(PlatformHandle h, msg.msg_control = cmsg_buf; msg.msg_controllen = sizeof(cmsg_buf); + // We use SO_PEEK_OFF to hold a common identifier between sockets to detect if + // they're connected. recvmsg modifies it, so we cache it and set it again + // after the call. + int id = 0; + socklen_t peek_off_size = sizeof(id); + getsockopt(h.fd, SOL_SOCKET, SO_PEEK_OFF, &id, &peek_off_size); ssize_t result = HANDLE_EINTR(recvmsg(h.fd, &msg, MSG_DONTWAIT)); if (result < 0) return result; + setsockopt(h.fd, SOL_SOCKET, SO_PEEK_OFF, &id, sizeof(id)); + // Success; no control messages. if (msg.msg_controllen == 0) return result; diff --git a/mojo/edk/embedder/platform_channel_utils_posix.h b/mojo/edk/embedder/platform_channel_utils_posix.h index 00e6a16..ad58753 100644 --- a/mojo/edk/embedder/platform_channel_utils_posix.h +++ b/mojo/edk/embedder/platform_channel_utils_posix.h @@ -20,9 +20,8 @@ namespace mojo { namespace edk { // The maximum number of handles that can be sent "at once" using -// |PlatformChannelSendmsgWithHandles()|. -// TODO(vtl): This number is taken from ipc/ipc_message_attachment_set.h: -// |IPC::MessageAttachmentSet::kMaxDescriptorsPerMessage|. +// |PlatformChannelSendmsgWithHandles()|. This must be less than the Linux +// kernel's SCM_MAX_FD which is 253. const size_t kPlatformChannelMaxNumHandles = 128; // Use these to write to a socket created using |PlatformChannelPair| (or diff --git a/mojo/edk/system/core.cc b/mojo/edk/system/core.cc index b6e18f7..72d9338 100644 --- a/mojo/edk/system/core.cc +++ b/mojo/edk/system/core.cc @@ -205,8 +205,10 @@ MojoResult Core::CreateMessagePipe( } PlatformChannelPair channel_pair; - dispatcher0->Init(channel_pair.PassServerHandle(), nullptr, 0u, nullptr, 0u); - dispatcher1->Init(channel_pair.PassClientHandle(), nullptr, 0u, nullptr, 0u); + dispatcher0->Init(channel_pair.PassServerHandle(), nullptr, 0u, nullptr, 0u, + nullptr, nullptr); + dispatcher1->Init(channel_pair.PassClientHandle(), nullptr, 0u, nullptr, 0u, + nullptr, nullptr); *message_pipe_handle0 = handle_pair.first; *message_pipe_handle1 = handle_pair.second; diff --git a/mojo/edk/system/core_unittest.cc b/mojo/edk/system/core_unittest.cc index bd7dfd9..28a038c 100644 --- a/mojo/edk/system/core_unittest.cc +++ b/mojo/edk/system/core_unittest.cc @@ -29,183 +29,183 @@ using CoreTest = test::CoreTestBase; TEST_F(CoreTest, GetTimeTicksNow) { const MojoTimeTicks start = core()->GetTimeTicksNow(); - EXPECT_NE(static_cast<MojoTimeTicks>(0), start) + ASSERT_NE(static_cast<MojoTimeTicks>(0), start) << "GetTimeTicksNow should return nonzero value"; test::Sleep(test::DeadlineFromMilliseconds(15)); const MojoTimeTicks finish = core()->GetTimeTicksNow(); // Allow for some fuzz in sleep. - EXPECT_GE((finish - start), static_cast<MojoTimeTicks>(8000)) + ASSERT_GE((finish - start), static_cast<MojoTimeTicks>(8000)) << "Sleeping should result in increasing time ticks"; } TEST_F(CoreTest, Basic) { MockHandleInfo info; - EXPECT_EQ(0u, info.GetCtorCallCount()); + ASSERT_EQ(0u, info.GetCtorCallCount()); MojoHandle h = CreateMockHandle(&info); - EXPECT_EQ(1u, info.GetCtorCallCount()); - EXPECT_NE(h, MOJO_HANDLE_INVALID); + ASSERT_EQ(1u, info.GetCtorCallCount()); + ASSERT_NE(h, MOJO_HANDLE_INVALID); - EXPECT_EQ(0u, info.GetWriteMessageCallCount()); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(0u, info.GetWriteMessageCallCount()); + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h, nullptr, 0, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, info.GetWriteMessageCallCount()); + ASSERT_EQ(1u, info.GetWriteMessageCallCount()); - EXPECT_EQ(0u, info.GetReadMessageCallCount()); + ASSERT_EQ(0u, info.GetReadMessageCallCount()); uint32_t num_bytes = 0; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, &num_bytes, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, info.GetReadMessageCallCount()); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(1u, info.GetReadMessageCallCount()); + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, nullptr, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(2u, info.GetReadMessageCallCount()); + ASSERT_EQ(2u, info.GetReadMessageCallCount()); - EXPECT_EQ(0u, info.GetWriteDataCallCount()); - EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, + ASSERT_EQ(0u, info.GetWriteDataCallCount()); + ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->WriteData(h, nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE)); - EXPECT_EQ(1u, info.GetWriteDataCallCount()); + ASSERT_EQ(1u, info.GetWriteDataCallCount()); - EXPECT_EQ(0u, info.GetBeginWriteDataCallCount()); - EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, + ASSERT_EQ(0u, info.GetBeginWriteDataCallCount()); + ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->BeginWriteData(h, nullptr, nullptr, MOJO_WRITE_DATA_FLAG_NONE)); - EXPECT_EQ(1u, info.GetBeginWriteDataCallCount()); + ASSERT_EQ(1u, info.GetBeginWriteDataCallCount()); - EXPECT_EQ(0u, info.GetEndWriteDataCallCount()); - EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0)); - EXPECT_EQ(1u, info.GetEndWriteDataCallCount()); + ASSERT_EQ(0u, info.GetEndWriteDataCallCount()); + ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0)); + ASSERT_EQ(1u, info.GetEndWriteDataCallCount()); - EXPECT_EQ(0u, info.GetReadDataCallCount()); - EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, + ASSERT_EQ(0u, info.GetReadDataCallCount()); + ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->ReadData(h, nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE)); - EXPECT_EQ(1u, info.GetReadDataCallCount()); + ASSERT_EQ(1u, info.GetReadDataCallCount()); - EXPECT_EQ(0u, info.GetBeginReadDataCallCount()); - EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, + ASSERT_EQ(0u, info.GetBeginReadDataCallCount()); + ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->BeginReadData(h, nullptr, nullptr, MOJO_READ_DATA_FLAG_NONE)); - EXPECT_EQ(1u, info.GetBeginReadDataCallCount()); + ASSERT_EQ(1u, info.GetBeginReadDataCallCount()); - EXPECT_EQ(0u, info.GetEndReadDataCallCount()); - EXPECT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0)); - EXPECT_EQ(1u, info.GetEndReadDataCallCount()); + ASSERT_EQ(0u, info.GetEndReadDataCallCount()); + ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0)); + ASSERT_EQ(1u, info.GetEndReadDataCallCount()); - EXPECT_EQ(0u, info.GetAddAwakableCallCount()); - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(0u, info.GetAddAwakableCallCount()); + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE, nullptr)); - EXPECT_EQ(1u, info.GetAddAwakableCallCount()); - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(1u, info.GetAddAwakableCallCount()); + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 0, nullptr)); - EXPECT_EQ(2u, info.GetAddAwakableCallCount()); + ASSERT_EQ(2u, info.GetAddAwakableCallCount()); MojoHandleSignalsState hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE, &hss)); - EXPECT_EQ(3u, info.GetAddAwakableCallCount()); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(0u, hss.satisfiable_signals); - EXPECT_EQ( + ASSERT_EQ(3u, info.GetAddAwakableCallCount()); + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(0u, hss.satisfiable_signals); + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, nullptr)); - EXPECT_EQ(4u, info.GetAddAwakableCallCount()); + ASSERT_EQ(4u, info.GetAddAwakableCallCount()); hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(h, ~MOJO_HANDLE_SIGNAL_NONE, 10 * 1000, &hss)); - EXPECT_EQ(5u, info.GetAddAwakableCallCount()); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(0u, hss.satisfiable_signals); + ASSERT_EQ(5u, info.GetAddAwakableCallCount()); + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(0u, hss.satisfiable_signals); MojoHandleSignals handle_signals = ~MOJO_HANDLE_SIGNAL_NONE; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr)); - EXPECT_EQ(6u, info.GetAddAwakableCallCount()); + ASSERT_EQ(6u, info.GetAddAwakableCallCount()); uint32_t result_index = static_cast<uint32_t>(-1); - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index, nullptr)); - EXPECT_EQ(7u, info.GetAddAwakableCallCount()); - EXPECT_EQ(0u, result_index); + ASSERT_EQ(7u, info.GetAddAwakableCallCount()); + ASSERT_EQ(0u, result_index); hss = kFullMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE, nullptr, &hss)); - EXPECT_EQ(8u, info.GetAddAwakableCallCount()); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(0u, hss.satisfiable_signals); + ASSERT_EQ(8u, info.GetAddAwakableCallCount()); + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(0u, hss.satisfiable_signals); result_index = static_cast<uint32_t>(-1); hss = kFullMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->WaitMany(&h, &handle_signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index, &hss)); - EXPECT_EQ(9u, info.GetAddAwakableCallCount()); - EXPECT_EQ(0u, result_index); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(0u, hss.satisfiable_signals); - - EXPECT_EQ(0u, info.GetDtorCallCount()); - EXPECT_EQ(0u, info.GetCloseCallCount()); - EXPECT_EQ(0u, info.GetCancelAllAwakablesCallCount()); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); - EXPECT_EQ(1u, info.GetCancelAllAwakablesCallCount()); - EXPECT_EQ(1u, info.GetCloseCallCount()); - EXPECT_EQ(1u, info.GetDtorCallCount()); + ASSERT_EQ(9u, info.GetAddAwakableCallCount()); + ASSERT_EQ(0u, result_index); + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(0u, hss.satisfiable_signals); + + ASSERT_EQ(0u, info.GetDtorCallCount()); + ASSERT_EQ(0u, info.GetCloseCallCount()); + ASSERT_EQ(0u, info.GetCancelAllAwakablesCallCount()); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h)); + ASSERT_EQ(1u, info.GetCancelAllAwakablesCallCount()); + ASSERT_EQ(1u, info.GetCloseCallCount()); + ASSERT_EQ(1u, info.GetDtorCallCount()); // No awakables should ever have ever been added. - EXPECT_EQ(0u, info.GetRemoveAwakableCallCount()); + ASSERT_EQ(0u, info.GetRemoveAwakableCallCount()); } TEST_F(CoreTest, InvalidArguments) { // |Close()|: { - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000)); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(MOJO_HANDLE_INVALID)); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(10)); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(1000000000)); // Test a double-close. MockHandleInfo info; MojoHandle h = CreateMockHandle(&info); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); - EXPECT_EQ(1u, info.GetCloseCallCount()); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h)); - EXPECT_EQ(1u, info.GetCloseCallCount()); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h)); + ASSERT_EQ(1u, info.GetCloseCallCount()); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h)); + ASSERT_EQ(1u, info.GetCloseCallCount()); } // |Wait()|: { - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE, nullptr)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE, nullptr)); MojoHandleSignalsState hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Wait(MOJO_HANDLE_INVALID, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE, &hss)); // On invalid argument, it shouldn't modify the handle signals state. - EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, + ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals, hss.satisfied_signals); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, + ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, hss.satisfiable_signals); hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Wait(10, ~MOJO_HANDLE_SIGNAL_NONE, MOJO_DEADLINE_INDEFINITE, &hss)); // On invalid argument, it shouldn't modify the handle signals state. - EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, + ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals, hss.satisfied_signals); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, + ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, hss.satisfiable_signals); } @@ -214,11 +214,11 @@ TEST_F(CoreTest, InvalidArguments) { MojoHandle handles[2] = {MOJO_HANDLE_INVALID, MOJO_HANDLE_INVALID}; MojoHandleSignals signals[2] = {~MOJO_HANDLE_SIGNAL_NONE, ~MOJO_HANDLE_SIGNAL_NONE}; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany(handles, signals, 0, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany(nullptr, signals, 0, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr)); // If |num_handles| is invalid, it should leave |result_index| and @@ -226,19 +226,19 @@ TEST_F(CoreTest, InvalidArguments) { // (We use -1 internally; make sure that doesn't leak.) uint32_t result_index = 123; MojoHandleSignalsState hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany(nullptr, signals, 0, MOJO_DEADLINE_INDEFINITE, &result_index, &hss)); - EXPECT_EQ(123u, result_index); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, + ASSERT_EQ(123u, result_index); + ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals, hss.satisfied_signals); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, + ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, hss.satisfiable_signals); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany(handles, nullptr, 0, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr)); - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany(handles, signals, 1, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr)); @@ -246,14 +246,14 @@ TEST_F(CoreTest, InvalidArguments) { // |signals_states| alone. result_index = static_cast<uint32_t>(-1); hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany( handles, signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index, &hss)); - EXPECT_EQ(0u, result_index); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, + ASSERT_EQ(0u, result_index); + ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals, hss.satisfied_signals); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, + ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, hss.satisfiable_signals); MockHandleInfo info[2]; @@ -261,33 +261,33 @@ TEST_F(CoreTest, InvalidArguments) { result_index = static_cast<uint32_t>(-1); hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->WaitMany( handles, signals, 1, MOJO_DEADLINE_INDEFINITE, &result_index, &hss)); - EXPECT_EQ(0u, result_index); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(0u, hss.satisfiable_signals); + ASSERT_EQ(0u, result_index); + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(0u, hss.satisfiable_signals); // On invalid argument, it'll leave |signals_states| alone. result_index = static_cast<uint32_t>(-1); hss = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany( handles, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index, &hss)); - EXPECT_EQ(1u, result_index); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfied_signals, + ASSERT_EQ(1u, result_index); + ASSERT_EQ(kFullMojoHandleSignalsState.satisfied_signals, hss.satisfied_signals); - EXPECT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, + ASSERT_EQ(kFullMojoHandleSignalsState.satisfiable_signals, hss.satisfiable_signals); handles[1] = handles[0] + 1; // Invalid handle. - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->WaitMany(handles, signals, 2, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr)); handles[1] = CreateMockHandle(&info[1]); - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->WaitMany(handles, signals, 2, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr)); @@ -295,8 +295,8 @@ TEST_F(CoreTest, InvalidArguments) { // TODO(vtl): Test one where we get "failed precondition" only for the // second handle (and the first one is valid to wait on). - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(handles[0])); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(handles[1])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(handles[0])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(handles[1])); } // |CreateMessagePipe()|: Nothing to check (apart from things that cause @@ -306,7 +306,7 @@ TEST_F(CoreTest, InvalidArguments) { // Only check arguments checked by |Core|, namely |handle|, |handles|, and // |num_handles|. { - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->WriteMessage(MOJO_HANDLE_INVALID, nullptr, 0, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); @@ -319,89 +319,89 @@ TEST_F(CoreTest, InvalidArguments) { // Note: This may return either |MOJO_RESULT_INVALID_ARGUMENT| or // |MOJO_RESULT_RESOURCE_EXHAUSTED|, depending on whether it's plausible or // not. - EXPECT_NE( + ASSERT_NE( MOJO_RESULT_OK, core()->WriteMessage(h, nullptr, 0, handles, std::numeric_limits<uint32_t>::max(), MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(0u, info.GetWriteMessageCallCount()); + ASSERT_EQ(0u, info.GetWriteMessageCallCount()); // Huge handle count (plausibly big). - EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, + ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, core()->WriteMessage( h, nullptr, 0, handles, std::numeric_limits<uint32_t>::max() / sizeof(handles[0]), MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(0u, info.GetWriteMessageCallCount()); + ASSERT_EQ(0u, info.GetWriteMessageCallCount()); // Invalid handle in |handles|. - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->WriteMessage(h, nullptr, 0, handles, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(0u, info.GetWriteMessageCallCount()); + ASSERT_EQ(0u, info.GetWriteMessageCallCount()); // Two invalid handles in |handles|. - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->WriteMessage(h, nullptr, 0, handles, 2, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(0u, info.GetWriteMessageCallCount()); + ASSERT_EQ(0u, info.GetWriteMessageCallCount()); // Can't send a handle over itself. handles[0] = h; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_BUSY, core()->WriteMessage(h, nullptr, 0, handles, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(0u, info.GetWriteMessageCallCount()); + ASSERT_EQ(0u, info.GetWriteMessageCallCount()); MockHandleInfo info2; MojoHandle h2 = CreateMockHandle(&info2); // This is "okay", but |MockDispatcher| doesn't implement it. handles[0] = h2; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_UNIMPLEMENTED, core()->WriteMessage(h, nullptr, 0, handles, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, info.GetWriteMessageCallCount()); + ASSERT_EQ(1u, info.GetWriteMessageCallCount()); // One of the |handles| is still invalid. - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->WriteMessage(h, nullptr, 0, handles, 2, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, info.GetWriteMessageCallCount()); + ASSERT_EQ(1u, info.GetWriteMessageCallCount()); // One of the |handles| is the same as |handle|. handles[1] = h; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_BUSY, core()->WriteMessage(h, nullptr, 0, handles, 2, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, info.GetWriteMessageCallCount()); + ASSERT_EQ(1u, info.GetWriteMessageCallCount()); // Can't send a handle twice in the same message. handles[1] = h2; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_BUSY, core()->WriteMessage(h, nullptr, 0, handles, 2, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, info.GetWriteMessageCallCount()); + ASSERT_EQ(1u, info.GetWriteMessageCallCount()); // Note: Since we never successfully sent anything with it, |h2| should // still be valid. - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h2)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h2)); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h)); } // |ReadMessage()|: // Only check arguments checked by |Core|, namely |handle|, |handles|, and // |num_handles|. { - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->ReadMessage(MOJO_HANDLE_INVALID, nullptr, nullptr, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); @@ -411,14 +411,14 @@ TEST_F(CoreTest, InvalidArguments) { // Okay. uint32_t handle_count = 0; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h, nullptr, nullptr, nullptr, &handle_count, MOJO_READ_MESSAGE_FLAG_NONE)); // Checked by |Core|, shouldn't go through to the dispatcher. - EXPECT_EQ(1u, info.GetReadMessageCallCount()); + ASSERT_EQ(1u, info.GetReadMessageCallCount()); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h)); } } @@ -435,11 +435,11 @@ TEST_F(CoreTest, InvalidArgumentsDeath) { { MojoHandle handle = MOJO_HANDLE_INVALID; MojoHandleSignals signals = ~MOJO_HANDLE_SIGNAL_NONE; - EXPECT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED( core()->WaitMany(nullptr, &signals, 1, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr), kMemoryCheckFailedRegex); - EXPECT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED( core()->WaitMany(&handle, nullptr, 1, MOJO_DEADLINE_INDEFINITE, nullptr, nullptr), kMemoryCheckFailedRegex); @@ -450,13 +450,13 @@ TEST_F(CoreTest, InvalidArgumentsDeath) { // |CreateMessagePipe()|: { MojoHandle h; - EXPECT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED( core()->CreateMessagePipe(nullptr, nullptr, nullptr), kMemoryCheckFailedRegex); - EXPECT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED( core()->CreateMessagePipe(nullptr, &h, nullptr), kMemoryCheckFailedRegex); - EXPECT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED( core()->CreateMessagePipe(nullptr, nullptr, &h), kMemoryCheckFailedRegex); } @@ -469,12 +469,12 @@ TEST_F(CoreTest, InvalidArgumentsDeath) { MojoHandle h = CreateMockHandle(&info); // Null |handles| with nonzero |num_handles|. - EXPECT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED( core()->WriteMessage(h, nullptr, 0, nullptr, 1, MOJO_WRITE_MESSAGE_FLAG_NONE), kMemoryCheckFailedRegex); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h)); } // |ReadMessage()|: @@ -485,12 +485,12 @@ TEST_F(CoreTest, InvalidArgumentsDeath) { MojoHandle h = CreateMockHandle(&info); uint32_t handle_count = 1; - EXPECT_DEATH_IF_SUPPORTED( + ASSERT_DEATH_IF_SUPPORTED( core()->ReadMessage(h, nullptr, nullptr, nullptr, &handle_count, MOJO_READ_MESSAGE_FLAG_NONE), kMemoryCheckFailedRegex); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h)); } } @@ -503,11 +503,11 @@ TEST_F(CoreTest, MessagePipe) { MojoHandleSignalsState hss[2]; uint32_t result_index; - EXPECT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h[0], &h[1])); + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h[0], &h[1])); // Should get two distinct, valid handles. - EXPECT_NE(h[0], MOJO_HANDLE_INVALID); - EXPECT_NE(h[1], MOJO_HANDLE_INVALID); - EXPECT_NE(h[0], h[1]); + ASSERT_NE(h[0], MOJO_HANDLE_INVALID); + ASSERT_NE(h[1], MOJO_HANDLE_INVALID); + ASSERT_NE(h[0], h[1]); // Neither should be readable. MojoHandleSignals signals[2] = {MOJO_HANDLE_SIGNAL_READABLE, @@ -515,37 +515,37 @@ TEST_F(CoreTest, MessagePipe) { result_index = static_cast<uint32_t>(-1); hss[0] = kEmptyMojoHandleSignalsState; hss[1] = kEmptyMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_DEADLINE_EXCEEDED, core()->WaitMany(h, signals, 2, 0, &result_index, hss)); - EXPECT_EQ(static_cast<uint32_t>(-1), result_index); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[0].satisfiable_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[1].satisfiable_signals); + ASSERT_EQ(static_cast<uint32_t>(-1), result_index); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals); // Try to read anyway. char buffer[1] = {'a'}; uint32_t buffer_size = 1; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_SHOULD_WAIT, core()->ReadMessage(h[0], buffer, &buffer_size, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); // Check that it left its inputs alone. - EXPECT_EQ('a', buffer[0]); - EXPECT_EQ(1u, buffer_size); + ASSERT_EQ('a', buffer[0]); + ASSERT_EQ(1u, buffer_size); // Both should be writable. hss[0] = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(h[0], MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[0], MOJO_HANDLE_SIGNAL_WRITABLE, 1000000000, &hss[0])); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[0].satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals); hss[0] = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE, 1000000000, &hss[0])); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[0].satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals); // Also check that |h[1]| is writable using |WaitMany()|. signals[0] = MOJO_HANDLE_SIGNAL_READABLE; @@ -553,19 +553,19 @@ TEST_F(CoreTest, MessagePipe) { result_index = static_cast<uint32_t>(-1); hss[0] = kEmptyMojoHandleSignalsState; hss[1] = kEmptyMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_OK, core()->WaitMany(h, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index, hss)); - EXPECT_EQ(1u, result_index); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[0].satisfiable_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[1].satisfiable_signals); + ASSERT_EQ(1u, result_index); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals); // Write to |h[1]|. buffer[0] = 'b'; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_OK, core()->WriteMessage(h[1], buffer, 1, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); @@ -576,97 +576,97 @@ TEST_F(CoreTest, MessagePipe) { result_index = static_cast<uint32_t>(-1); hss[0] = kEmptyMojoHandleSignalsState; hss[1] = kEmptyMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_OK, core()->WaitMany(h, signals, 2, MOJO_DEADLINE_INDEFINITE, &result_index, hss)); - EXPECT_EQ(0u, result_index); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(0u, result_index); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[0].satisfiable_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[1].satisfiable_signals); + ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[1].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[1].satisfiable_signals); // Read from |h[0]|. // First, get only the size. buffer_size = 0; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_RESOURCE_EXHAUSTED, core()->ReadMessage(h[0], nullptr, &buffer_size, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(1u, buffer_size); + ASSERT_EQ(1u, buffer_size); // Then actually read it. buffer[0] = 'c'; buffer_size = 1; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_OK, core()->ReadMessage(h[0], buffer, &buffer_size, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ('b', buffer[0]); - EXPECT_EQ(1u, buffer_size); + ASSERT_EQ('b', buffer[0]); + ASSERT_EQ(1u, buffer_size); // |h[0]| should no longer be readable. hss[0] = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, + ASSERT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, core()->Wait(h[0], MOJO_HANDLE_SIGNAL_READABLE, 0, &hss[0])); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); - EXPECT_EQ(kAllSignals, hss[0].satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals); + ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals); // Write to |h[0]|. buffer[0] = 'd'; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_OK, core()->WriteMessage(h[0], buffer, 1, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); // Close |h[0]|. - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[0])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[0])); // Wait for |h[1]| to learn about the other end's closure. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_PEER_CLOSED, 1000000000, &hss[0])); // Check that |h[1]| is no longer writable (and will never be). hss[0] = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_WRITABLE, 1000000000, &hss[0])); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfiable_signals); // Check that |h[1]| is still readable (for the moment). hss[0] = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss[0])); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfiable_signals); // Discard a message from |h[1]|. - EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, + ASSERT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, core()->ReadMessage(h[1], nullptr, nullptr, nullptr, nullptr, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); // |h[1]| is no longer readable (and will never be). hss[0] = kFullMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(h[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss[0])); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[0].satisfiable_signals); // Try writing to |h[1]|. buffer[0] = 'e'; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->WriteMessage(h[1], buffer, 1, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h[1])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[1])); } // Tests passing a message pipe handle. @@ -684,208 +684,208 @@ TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) { MojoHandle h_received; MojoHandle h_passing[2]; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1])); // Make sure that |h_passing[]| work properly. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passing[0], kHello, kHelloSize, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(kAllSignals, hss.satisfiable_signals); + ASSERT_EQ(kAllSignals, hss.satisfiable_signals); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_passing[1], buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, num_bytes); - EXPECT_STREQ(kHello, buffer); - EXPECT_EQ(0u, num_handles); + ASSERT_EQ(kHelloSize, num_bytes); + ASSERT_STREQ(kHello, buffer); + ASSERT_EQ(0u, num_handles); // Make sure that you can't pass either of the message pipe's handles over // itself. - EXPECT_EQ(MOJO_RESULT_BUSY, + ASSERT_EQ(MOJO_RESULT_BUSY, core()->WriteMessage(h_passing[0], kHello, kHelloSize, &h_passing[0], 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->WriteMessage(h_passing[0], kHello, kHelloSize, &h_passing[1], 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); MojoHandle h_passed[2]; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h_passed[0], &h_passed[1])); // Make sure that |h_passed[]| work properly. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passed[0], kHello, kHelloSize, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_passed[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(kAllSignals, hss.satisfiable_signals); + ASSERT_EQ(kAllSignals, hss.satisfiable_signals); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_passed[1], buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, num_bytes); - EXPECT_STREQ(kHello, buffer); - EXPECT_EQ(0u, num_handles); + ASSERT_EQ(kHelloSize, num_bytes); + ASSERT_STREQ(kHello, buffer); + ASSERT_EQ(0u, num_handles); // Send |h_passed[1]| from |h_passing[0]| to |h_passing[1]|. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passing[0], kWorld, kWorldSize, &h_passed[1], 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(kAllSignals, hss.satisfiable_signals); + ASSERT_EQ(kAllSignals, hss.satisfiable_signals); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_passing[1], buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kWorldSize, num_bytes); - EXPECT_STREQ(kWorld, buffer); - EXPECT_EQ(1u, num_handles); + ASSERT_EQ(kWorldSize, num_bytes); + ASSERT_STREQ(kWorld, buffer); + ASSERT_EQ(1u, num_handles); h_received = handles[0]; - EXPECT_NE(h_received, MOJO_HANDLE_INVALID); - EXPECT_NE(h_received, h_passing[0]); - EXPECT_NE(h_received, h_passing[1]); - EXPECT_NE(h_received, h_passed[0]); + ASSERT_NE(h_received, MOJO_HANDLE_INVALID); + ASSERT_NE(h_received, h_passing[0]); + ASSERT_NE(h_received, h_passing[1]); + ASSERT_NE(h_received, h_passed[0]); // Note: We rely on the Mojo system not re-using handle values very often. - EXPECT_NE(h_received, h_passed[1]); + ASSERT_NE(h_received, h_passed[1]); // |h_passed[1]| should no longer be valid; check that trying to close it // fails. See above note. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h_passed[1])); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(h_passed[1])); // Write to |h_passed[0]|. Should receive on |h_received|. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passed[0], kHello, kHelloSize, nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(kAllSignals, hss.satisfiable_signals); + ASSERT_EQ(kAllSignals, hss.satisfiable_signals); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_received, buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, num_bytes); - EXPECT_STREQ(kHello, buffer); - EXPECT_EQ(0u, num_handles); - - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passed[0])); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_received)); + ASSERT_EQ(kHelloSize, num_bytes); + ASSERT_STREQ(kHello, buffer); + ASSERT_EQ(0u, num_handles); + + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passed[0])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_received)); } TEST_F(CoreTest, DataPipe) { MojoHandle ph, ch; // p is for producer and c is for consumer. MojoHandleSignalsState hss; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateDataPipe(nullptr, &ph, &ch)); // Should get two distinct, valid handles. - EXPECT_NE(ph, MOJO_HANDLE_INVALID); - EXPECT_NE(ch, MOJO_HANDLE_INVALID); - EXPECT_NE(ph, ch); + ASSERT_NE(ph, MOJO_HANDLE_INVALID); + ASSERT_NE(ch, MOJO_HANDLE_INVALID); + ASSERT_NE(ph, ch); // Producer should be never-readable, but already writable. hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(ph, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ph, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); // Consumer should be never-writable, and not yet readable. hss = kFullMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(ch, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss)); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); hss = kFullMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_DEADLINE_EXCEEDED, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); // Write. signed char elements[2] = {'A', 'B'}; uint32_t num_bytes = 2u; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteData(ph, elements, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); - EXPECT_EQ(2u, num_bytes); + ASSERT_EQ(2u, num_bytes); // Wait for the data to arrive to the consumer. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); // Consumer should now be readable. hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); // Peek one character. elements[0] = -1; elements[1] = -1; num_bytes = 1u; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData( ch, elements, &num_bytes, MOJO_READ_DATA_FLAG_NONE | MOJO_READ_DATA_FLAG_PEEK)); - EXPECT_EQ('A', elements[0]); - EXPECT_EQ(-1, elements[1]); + ASSERT_EQ('A', elements[0]); + ASSERT_EQ(-1, elements[1]); // Read one character. elements[0] = -1; elements[1] = -1; num_bytes = 1u; - EXPECT_EQ(MOJO_RESULT_OK, core()->ReadData(ch, elements, &num_bytes, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData(ch, elements, &num_bytes, MOJO_READ_DATA_FLAG_NONE)); - EXPECT_EQ('A', elements[0]); - EXPECT_EQ(-1, elements[1]); + ASSERT_EQ('A', elements[0]); + ASSERT_EQ(-1, elements[1]); // Two-phase write. void* write_ptr = nullptr; @@ -899,7 +899,7 @@ TEST_F(CoreTest, DataPipe) { // Trying to do a normal write during a two-phase write should fail. elements[0] = 'X'; num_bytes = 1u; - EXPECT_EQ(MOJO_RESULT_BUSY, + ASSERT_EQ(MOJO_RESULT_BUSY, core()->WriteData(ph, elements, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); @@ -907,50 +907,50 @@ TEST_F(CoreTest, DataPipe) { static_cast<char*>(write_ptr)[0] = 'C'; static_cast<char*>(write_ptr)[1] = 'D'; static_cast<char*>(write_ptr)[2] = 'E'; - EXPECT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u)); + ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u)); // Wait for the data to arrive to the consumer. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); // Query how much data we have. num_bytes = 0; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData(ch, nullptr, &num_bytes, MOJO_READ_DATA_FLAG_QUERY)); - EXPECT_GE(num_bytes, 1u); + ASSERT_GE(num_bytes, 1u); // Try to query with peek. Should fail. num_bytes = 0; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->ReadData(ch, nullptr, &num_bytes, MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK)); - EXPECT_EQ(0u, num_bytes); + ASSERT_EQ(0u, num_bytes); // Try to discard ten characters, in all-or-none mode. Should fail. num_bytes = 10; - EXPECT_EQ(MOJO_RESULT_OUT_OF_RANGE, + ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE, core()->ReadData( ch, nullptr, &num_bytes, MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE)); // Try to discard two characters, in peek mode. Should fail. num_bytes = 2; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_INVALID_ARGUMENT, core()->ReadData(ch, nullptr, &num_bytes, MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK)); // Discard a character. num_bytes = 1; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData( ch, nullptr, &num_bytes, MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE)); // Ensure the 3 bytes were read. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); // Try a two-phase read of the remaining three bytes with peek. Should fail. @@ -970,43 +970,43 @@ TEST_F(CoreTest, DataPipe) { // Discarding right now should fail. num_bytes = 1; - EXPECT_EQ(MOJO_RESULT_BUSY, + ASSERT_EQ(MOJO_RESULT_BUSY, core()->ReadData(ch, nullptr, &num_bytes, MOJO_READ_DATA_FLAG_DISCARD)); // Actually check our data and end the two-phase read. - EXPECT_EQ('C', static_cast<const char*>(read_ptr)[0]); - EXPECT_EQ('D', static_cast<const char*>(read_ptr)[1]); - EXPECT_EQ('E', static_cast<const char*>(read_ptr)[2]); - EXPECT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 3u)); + ASSERT_EQ('C', static_cast<const char*>(read_ptr)[0]); + ASSERT_EQ('D', static_cast<const char*>(read_ptr)[1]); + ASSERT_EQ('E', static_cast<const char*>(read_ptr)[2]); + ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 3u)); // Consumer should now be no longer readable. hss = kFullMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_DEADLINE_EXCEEDED, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); - EXPECT_EQ(0u, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(0u, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); // TODO(vtl): More. // Close the producer. - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ph)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph)); // Wait for this to get to the consumer. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_PEER_CLOSED, 1000000000, &hss)); // The consumer should now be never-readable. hss = kFullMojoHandleSignalsState; - EXPECT_EQ( + ASSERT_EQ( MOJO_RESULT_FAILED_PRECONDITION, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch)); } // Tests passing data pipe producer and consumer handles. @@ -1023,116 +1023,116 @@ TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing2) { MojoHandleSignalsState hss; MojoHandle h_passing[2]; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1])); MojoHandle ph, ch; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->CreateDataPipe(nullptr, &ph, &ch)); // Send |ch| from |h_passing[0]| to |h_passing[1]|. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(kAllSignals, hss.satisfiable_signals); + ASSERT_EQ(kAllSignals, hss.satisfiable_signals); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_passing[1], buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, num_bytes); - EXPECT_STREQ(kHello, buffer); - EXPECT_EQ(1u, num_handles); + ASSERT_EQ(kHelloSize, num_bytes); + ASSERT_STREQ(kHello, buffer); + ASSERT_EQ(1u, num_handles); MojoHandle ch_received = handles[0]; - EXPECT_NE(ch_received, MOJO_HANDLE_INVALID); - EXPECT_NE(ch_received, h_passing[0]); - EXPECT_NE(ch_received, h_passing[1]); - EXPECT_NE(ch_received, ph); + ASSERT_NE(ch_received, MOJO_HANDLE_INVALID); + ASSERT_NE(ch_received, h_passing[0]); + ASSERT_NE(ch_received, h_passing[1]); + ASSERT_NE(ch_received, ph); // Note: We rely on the Mojo system not re-using handle values very often. - EXPECT_NE(ch_received, ch); + ASSERT_NE(ch_received, ch); // |ch| should no longer be valid; check that trying to close it fails. See // above note. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ch)); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ch)); // Write to |ph|. Should receive on |ch_received|. num_bytes = kWorldSize; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteData(ph, kWorld, &num_bytes, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); num_bytes = kBufferSize; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData(ch_received, buffer, &num_bytes, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kWorldSize, num_bytes); - EXPECT_STREQ(kWorld, buffer); + ASSERT_EQ(kWorldSize, num_bytes); + ASSERT_STREQ(kWorld, buffer); // Now pass |ph| in the same direction. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passing[0], kWorld, kWorldSize, &ph, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(kAllSignals, hss.satisfiable_signals); + ASSERT_EQ(kAllSignals, hss.satisfiable_signals); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_passing[1], buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kWorldSize, num_bytes); - EXPECT_STREQ(kWorld, buffer); - EXPECT_EQ(1u, num_handles); + ASSERT_EQ(kWorldSize, num_bytes); + ASSERT_STREQ(kWorld, buffer); + ASSERT_EQ(1u, num_handles); MojoHandle ph_received = handles[0]; - EXPECT_NE(ph_received, MOJO_HANDLE_INVALID); - EXPECT_NE(ph_received, h_passing[0]); - EXPECT_NE(ph_received, h_passing[1]); - EXPECT_NE(ph_received, ch_received); + ASSERT_NE(ph_received, MOJO_HANDLE_INVALID); + ASSERT_NE(ph_received, h_passing[0]); + ASSERT_NE(ph_received, h_passing[1]); + ASSERT_NE(ph_received, ch_received); // Again, rely on the Mojo system not re-using handle values very often. - EXPECT_NE(ph_received, ph); + ASSERT_NE(ph_received, ph); // |ph| should no longer be valid; check that trying to close it fails. See // above note. - EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ph)); + ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT, core()->Close(ph)); // Write to |ph_received|. Should receive on |ch_received|. num_bytes = kHelloSize; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteData(ph_received, kHello, &num_bytes, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch_received, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); num_bytes = kBufferSize; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadData(ch_received, buffer, &num_bytes, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, num_bytes); - EXPECT_STREQ(kHello, buffer); + ASSERT_EQ(kHelloSize, num_bytes); + ASSERT_STREQ(kHello, buffer); ph = ph_received; ph_received = MOJO_HANDLE_INVALID; @@ -1146,40 +1146,40 @@ TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing2) { core()->BeginWriteData(ph, &write_ptr, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE)); ASSERT_GE(num_bytes, 1u); - EXPECT_EQ(MOJO_RESULT_BUSY, + ASSERT_EQ(MOJO_RESULT_BUSY, core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ph, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); // But |ch| can, even if |ph| is in a two-phase write. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); ch = MOJO_HANDLE_INVALID; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, nullptr)); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_passing[1], buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kHelloSize, num_bytes); - EXPECT_STREQ(kHello, buffer); - EXPECT_EQ(1u, num_handles); + ASSERT_EQ(kHelloSize, num_bytes); + ASSERT_STREQ(kHello, buffer); + ASSERT_EQ(1u, num_handles); ch = handles[0]; - EXPECT_NE(ch, MOJO_HANDLE_INVALID); + ASSERT_NE(ch, MOJO_HANDLE_INVALID); // Complete the two-phase write. static_cast<char*>(write_ptr)[0] = 'x'; - EXPECT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 1)); + ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 1)); // Wait for |ch| to be readable. hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(ch, MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); // Make sure that |ch| can't be sent if it's in a two-phase read. @@ -1188,42 +1188,42 @@ TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing2) { ASSERT_EQ(MOJO_RESULT_OK, core()->BeginReadData(ch, &read_ptr, &num_bytes, MOJO_READ_DATA_FLAG_ALL_OR_NONE)); - EXPECT_EQ(MOJO_RESULT_BUSY, + ASSERT_EQ(MOJO_RESULT_BUSY, core()->WriteMessage(h_passing[0], kHello, kHelloSize, &ch, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); // But |ph| can, even if |ch| is in a two-phase read. - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h_passing[0], kWorld, kWorldSize, &ph, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); ph = MOJO_HANDLE_INVALID; hss = kEmptyMojoHandleSignalsState; - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->Wait(h_passing[1], MOJO_HANDLE_SIGNAL_READABLE, 1000000000, &hss)); - EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, + ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); - EXPECT_EQ(kAllSignals, hss.satisfiable_signals); + ASSERT_EQ(kAllSignals, hss.satisfiable_signals); num_bytes = kBufferSize; num_handles = MOJO_ARRAYSIZE(handles); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage( h_passing[1], buffer, &num_bytes, handles, &num_handles, MOJO_READ_MESSAGE_FLAG_NONE)); - EXPECT_EQ(kWorldSize, num_bytes); - EXPECT_STREQ(kWorld, buffer); - EXPECT_EQ(1u, num_handles); + ASSERT_EQ(kWorldSize, num_bytes); + ASSERT_STREQ(kWorld, buffer); + ASSERT_EQ(1u, num_handles); ph = handles[0]; - EXPECT_NE(ph, MOJO_HANDLE_INVALID); + ASSERT_NE(ph, MOJO_HANDLE_INVALID); // Complete the two-phase read. - EXPECT_EQ('x', static_cast<const char*>(read_ptr)[0]); - EXPECT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 1)); + ASSERT_EQ('x', static_cast<const char*>(read_ptr)[0]); + ASSERT_EQ(MOJO_RESULT_OK, core()->EndReadData(ch, 1)); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ph)); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(ch)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1])); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch)); } struct TestAsyncWaiter { @@ -1239,23 +1239,23 @@ TEST_F(CoreTest, AsyncWait) { MockHandleInfo info; MojoHandle h = CreateMockHandle(&info); - EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, + ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, core()->AsyncWait(h, MOJO_HANDLE_SIGNAL_READABLE, base::Bind(&TestAsyncWaiter::Awake, base::Unretained(&waiter)))); - EXPECT_EQ(0u, info.GetAddedAwakableSize()); + ASSERT_EQ(0u, info.GetAddedAwakableSize()); info.AllowAddAwakable(true); - EXPECT_EQ(MOJO_RESULT_OK, + ASSERT_EQ(MOJO_RESULT_OK, core()->AsyncWait(h, MOJO_HANDLE_SIGNAL_READABLE, base::Bind(&TestAsyncWaiter::Awake, base::Unretained(&waiter)))); - EXPECT_EQ(1u, info.GetAddedAwakableSize()); + ASSERT_EQ(1u, info.GetAddedAwakableSize()); - EXPECT_FALSE(info.GetAddedAwakableAt(0)->Awake(MOJO_RESULT_BUSY, 0)); - EXPECT_EQ(MOJO_RESULT_BUSY, waiter.result); + ASSERT_FALSE(info.GetAddedAwakableAt(0)->Awake(MOJO_RESULT_BUSY, 0)); + ASSERT_EQ(MOJO_RESULT_BUSY, waiter.result); - EXPECT_EQ(MOJO_RESULT_OK, core()->Close(h)); + ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h)); } // TODO(vtl): Test |DuplicateBufferHandle()| and |MapBuffer()|. diff --git a/mojo/edk/system/data_pipe_consumer_dispatcher.cc b/mojo/edk/system/data_pipe_consumer_dispatcher.cc index 710d39b..d0db351 100644 --- a/mojo/edk/system/data_pipe_consumer_dispatcher.cc +++ b/mojo/edk/system/data_pipe_consumer_dispatcher.cc @@ -28,7 +28,8 @@ void DataPipeConsumerDispatcher::Init( if (message_pipe.is_valid()) { channel_ = RawChannel::Create(message_pipe.Pass()); channel_->SetSerializedData( - serialized_read_buffer, serialized_read_buffer_size, nullptr, 0u); + serialized_read_buffer, serialized_read_buffer_size, nullptr, 0u, + nullptr, nullptr); internal::g_io_thread_task_runner->PostTask( FROM_HERE, base::Bind(&DataPipeConsumerDispatcher::InitOnIO, this)); } else { @@ -478,12 +479,13 @@ void DataPipeConsumerDispatcher::SerializeInternal() { // so that other messages aren't read after this. if (channel_) { std::vector<char> serialized_write_buffer; + std::vector<int> fds; bool write_error = false; - serialized_platform_handle_ = - channel_->ReleaseHandle(&serialized_read_buffer_, - &serialized_write_buffer, - &write_error); + serialized_platform_handle_ = channel_->ReleaseHandle( + &serialized_read_buffer_, &serialized_write_buffer, &fds, &fds, + &write_error); CHECK(serialized_write_buffer.empty()); + CHECK(fds.empty()); CHECK(!write_error) << "DataPipeConsumerDispatcher doesn't write."; channel_ = nullptr; diff --git a/mojo/edk/system/data_pipe_producer_dispatcher.cc b/mojo/edk/system/data_pipe_producer_dispatcher.cc index 2b1a3e0..4989786 100644 --- a/mojo/edk/system/data_pipe_producer_dispatcher.cc +++ b/mojo/edk/system/data_pipe_producer_dispatcher.cc @@ -22,7 +22,8 @@ void DataPipeProducerDispatcher::Init( if (message_pipe.is_valid()) { channel_ = RawChannel::Create(message_pipe.Pass()); channel_->SetSerializedData( - nullptr, 0u, serialized_write_buffer, serialized_write_buffer_size); + nullptr, 0u, serialized_write_buffer, serialized_write_buffer_size, + nullptr, nullptr); internal::g_io_thread_task_runner->PostTask( FROM_HERE, base::Bind(&DataPipeProducerDispatcher::InitOnIO, this)); } else { @@ -385,10 +386,13 @@ void DataPipeProducerDispatcher::SerializeInternal() { // so that other messages aren't read after this. if (channel_) { std::vector<char> serialized_read_buffer; + std::vector<int> fds; bool write_error = false; serialized_platform_handle_ = channel_->ReleaseHandle( - &serialized_read_buffer, &serialized_write_buffer_, &write_error); + &serialized_read_buffer, &serialized_write_buffer_, &fds, &fds, + &write_error); CHECK(serialized_read_buffer.empty()); + CHECK(fds.empty()); if (write_error) serialized_platform_handle_.reset(); channel_ = nullptr; diff --git a/mojo/edk/system/data_pipe_unittest.cc b/mojo/edk/system/data_pipe_unittest.cc index 4625033..5c8f0f8 100644 --- a/mojo/edk/system/data_pipe_unittest.cc +++ b/mojo/edk/system/data_pipe_unittest.cc @@ -1616,7 +1616,7 @@ TEST_F(DataPipeTest, ConsumerWithClosedProducerSent) { ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); - int32 read_data; + int32_t read_data; ASSERT_EQ(MOJO_RESULT_OK, ReadData(&read_data, &num_bytes)); ASSERT_EQ(sizeof(read_data), num_bytes); ASSERT_EQ(data, read_data); diff --git a/mojo/edk/system/dispatcher.h b/mojo/edk/system/dispatcher.h index 575471f..b583bae 100644 --- a/mojo/edk/system/dispatcher.h +++ b/mojo/edk/system/dispatcher.h @@ -324,8 +324,7 @@ class MOJO_SYSTEM_IMPL_EXPORT Dispatcher // Starts the serialization. Returns (via the two "out" parameters) the // maximum amount of space that may be needed to serialize this dispatcher (no // more than |TransportData::kMaxSerializedDispatcherSize|) and the maximum - // number of |PlatformHandle|s that may need to be attached (no more than - // |TransportData::kMaxSerializedDispatcherPlatformHandles|). If this + // number of |PlatformHandle|s that may need to be attached. If this // dispatcher cannot be serialized, |*max_size| and |*max_platform_handles| // should be set to zero. A call to this method will ALWAYS be followed by a // call to |EndSerializeAndClose()| (even if this dispatcher cannot be diff --git a/mojo/edk/system/message_pipe_dispatcher.cc b/mojo/edk/system/message_pipe_dispatcher.cc index 6856def..90b3774 100644 --- a/mojo/edk/system/message_pipe_dispatcher.cc +++ b/mojo/edk/system/message_pipe_dispatcher.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "mojo/edk/embedder/embedder_internal.h" +#include "mojo/edk/embedder/platform_handle_utils.h" #include "mojo/edk/embedder/platform_shared_buffer.h" #include "mojo/edk/embedder/platform_support.h" #include "mojo/edk/system/configuration.h" @@ -38,6 +39,13 @@ struct MOJO_ALIGNAS(8) SerializedMessagePipeHandleDispatcher { size_t serialized_read_buffer_size; size_t serialized_write_buffer_size; size_t serialized_messagage_queue_size; + + // These are the FDs required as part of serializing channel_ and + // message_queue_. This is only used on POSIX. + size_t serialized_fds_index; // (Or |kInvalidMessagePipeHandleIndex|.) + size_t serialized_read_fds_length; + size_t serialized_write_fds_length; + size_t serialized_message_fds_length; }; char* SerializeBuffer(char* start, std::vector<char>* buffer) { @@ -65,6 +73,13 @@ bool GetHandle(size_t index, return true; } +#if defined(OS_POSIX) +void ClosePlatformHandles(std::vector<int>* fds) { + for (size_t i = 0; i < fds->size(); ++i) + PlatformHandle((*fds)[i]).CloseIfNecessary(); +} +#endif + } // namespace // MessagePipeDispatcher ------------------------------------------------------- @@ -104,14 +119,17 @@ MojoResult MessagePipeDispatcher::ValidateCreateOptions( void MessagePipeDispatcher::Init( ScopedPlatformHandle message_pipe, char* serialized_read_buffer, size_t serialized_read_buffer_size, - char* serialized_write_buffer, size_t serialized_write_buffer_size) { + char* serialized_write_buffer, size_t serialized_write_buffer_size, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds) { if (message_pipe.get().is_valid()) { channel_ = RawChannel::Create(message_pipe.Pass()); // TODO(jam): It's probably cleaner to pass this in Init call. channel_->SetSerializedData( serialized_read_buffer, serialized_read_buffer_size, - serialized_write_buffer, serialized_write_buffer_size); + serialized_write_buffer, serialized_write_buffer_size, + serialized_read_fds, serialized_write_fds); if (g_use_channel_on_io_thread_only) { internal::g_io_thread_task_runner->PostTask( FROM_HERE, base::Bind(&MessagePipeDispatcher::InitOnIO, this)); @@ -251,13 +269,38 @@ scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( scoped_refptr<MessagePipeDispatcher> rv( Create(MessagePipeDispatcher::kDefaultCreateOptions)); - rv->Init(platform_handle.Pass(), - serialized_read_buffer, - serialized_read_buffer_size, - serialized_write_buffer, - serialized_write_buffer_size); rv->write_error_ = serialization->write_error; + std::vector<int> serialized_read_fds; + std::vector<int> serialized_write_fds; +#if defined(OS_POSIX) + std::vector<int> serialized_fds; + size_t serialized_fds_index = 0; + + size_t total_fd_count = serialization->serialized_read_fds_length + + serialization->serialized_write_fds_length + + serialization->serialized_message_fds_length; + for (size_t i = 0; i < total_fd_count; ++i) { + ScopedPlatformHandle handle; + if (!GetHandle(serialization->serialized_fds_index + i, platform_handles, + &handle)) { + ClosePlatformHandles(&serialized_fds); + return nullptr; + } + serialized_fds.push_back(handle.release().fd); + } + + serialized_read_fds.assign( + serialized_fds.begin(), + serialized_fds.begin() + serialization->serialized_read_fds_length); + serialized_fds_index += serialization->serialized_read_fds_length; + serialized_write_fds.assign( + serialized_fds.begin() + serialized_fds_index, + serialized_fds.begin() + serialized_fds_index + + serialization->serialized_write_fds_length); + serialized_fds_index += serialization->serialized_write_fds_length; +#endif + while (message_queue_size) { size_t message_size; CHECK(MessageInTransit::GetNextMessageSize( @@ -277,6 +320,7 @@ scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( &platform_handle_table); if (num_platform_handles > 0) { +#if defined(OS_WIN) temp_platform_handles = GetReadPlatformHandles(num_platform_handles, platform_handle_table).Pass(); @@ -284,6 +328,12 @@ scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( LOG(ERROR) << "Invalid number of platform handles received"; return nullptr; } +#else + temp_platform_handles.reset(new PlatformHandleVector()); + for (size_t i = 0; i < num_platform_handles; ++i) + temp_platform_handles->push_back( + PlatformHandle(serialized_fds[serialized_fds_index++])); +#endif } } @@ -301,6 +351,14 @@ scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( rv->message_queue_.AddMessage(message.Pass()); } + rv->Init(platform_handle.Pass(), + serialized_read_buffer, + serialized_read_buffer_size, + serialized_write_buffer, + serialized_write_buffer_size, + &serialized_read_fds, + &serialized_write_fds); + if (message_queue_size) { // Should be empty by now. LOG(ERROR) << "Invalid queued messages"; return nullptr; @@ -312,6 +370,9 @@ scoped_refptr<MessagePipeDispatcher> MessagePipeDispatcher::Deserialize( MessagePipeDispatcher::MessagePipeDispatcher() : channel_(nullptr), serialized_(false), + serialized_read_fds_length_(0u), + serialized_write_fds_length_(0u), + serialized_message_fds_length_(0u), calling_init_(false), write_error_(false) { } @@ -319,6 +380,9 @@ MessagePipeDispatcher::MessagePipeDispatcher() MessagePipeDispatcher::~MessagePipeDispatcher() { // |Close()|/|CloseImplNoLock()| should have taken care of the channel. DCHECK(!channel_); +#if defined(OS_POSIX) + ClosePlatformHandles(&serialized_fds_); +#endif } void MessagePipeDispatcher::CancelAllAwakablesNoLock() { @@ -339,17 +403,24 @@ void MessagePipeDispatcher::CloseImplNoLock() { void MessagePipeDispatcher::SerializeInternal() { // We need to stop watching handle immediately, even though not on IO thread, // so that other messages aren't read after this. - { - if (channel_) { - bool write_error = false; - serialized_platform_handle_ = channel_->ReleaseHandle( - &serialized_read_buffer_, &serialized_write_buffer_, &write_error); - channel_ = nullptr; - if (write_error) - write_error = true; - } else { - // It's valid that the other side wrote some data and closed its end. - } + std::vector<int> serialized_read_fds, serialized_write_fds; + if (channel_) { + bool write_error = false; + + serialized_platform_handle_ = channel_->ReleaseHandle( + &serialized_read_buffer_, &serialized_write_buffer_, + &serialized_read_fds, &serialized_write_fds, &write_error); + serialized_fds_.insert(serialized_fds_.end(), serialized_read_fds.begin(), + serialized_read_fds.end()); + serialized_read_fds_length_ = serialized_read_fds.size(); + serialized_fds_.insert(serialized_fds_.end(), serialized_write_fds.begin(), + serialized_write_fds.end()); + serialized_write_fds_length_ = serialized_write_fds.size(); + channel_ = nullptr; + if (write_error) + write_error = true; + } else { + // It's valid that the other side wrote some data and closed its end. } DCHECK(serialized_message_queue_.empty()); @@ -383,35 +454,37 @@ void MessagePipeDispatcher::SerializeInternal() { // cont'd if (transport_data_buffer_size != 0) { -#if defined(OS_WIN) // TODO(jam): copied from RawChannelWin::WriteNoLock( - if (RawChannel::GetSerializedPlatformHandleSize()) { + PlatformHandleVector* all_platform_handles = + message->transport_data()->platform_handles(); + if (all_platform_handles) { +#if defined(OS_WIN) char* serialization_data = static_cast<char*>(message->transport_data()->buffer()) + message->transport_data()->platform_handle_table_offset(); - PlatformHandleVector* all_platform_handles = - message->transport_data()->platform_handles(); - if (all_platform_handles) { - DWORD current_process_id = base::GetCurrentProcId(); - for (size_t i = 0; i < all_platform_handles->size(); i++) { - *reinterpret_cast<DWORD*>(serialization_data) = current_process_id; - serialization_data += sizeof(DWORD); - *reinterpret_cast<HANDLE*>(serialization_data) = - all_platform_handles->at(i).handle; - serialization_data += sizeof(HANDLE); - all_platform_handles->at(i) = PlatformHandle(); - } + DWORD current_process_id = base::GetCurrentProcId(); + for (size_t i = 0; i < all_platform_handles->size(); i++) { + *reinterpret_cast<DWORD*>(serialization_data) = current_process_id; + serialization_data += sizeof(DWORD); + *reinterpret_cast<HANDLE*>(serialization_data) = + all_platform_handles->at(i).handle; + serialization_data += sizeof(HANDLE); + all_platform_handles->at(i) = PlatformHandle(); } - } +#else + for (size_t i = 0; i < all_platform_handles->size(); i++) { + serialized_fds_.push_back(all_platform_handles->at(i).fd); + serialized_message_fds_length_++; + all_platform_handles->at(i) = PlatformHandle(); + } +#endif serialized_message_queue_.insert( serialized_message_queue_.end(), static_cast<const char*>(message->transport_data()->buffer()), static_cast<const char*>(message->transport_data()->buffer()) + transport_data_buffer_size); -#else - NOTREACHED() << "TODO(jam) implement"; -#endif + } } for (size_t i = 0; i < dispatchers.size(); ++i) @@ -435,6 +508,10 @@ MessagePipeDispatcher::CreateEquivalentDispatcherAndCloseImplNoLock() { serialized_message_queue_.swap(rv->serialized_message_queue_); serialized_read_buffer_.swap(rv->serialized_read_buffer_); serialized_write_buffer_.swap(rv->serialized_write_buffer_); + serialized_fds_.swap(rv->serialized_fds_); + rv->serialized_read_fds_length_ = serialized_read_fds_length_; + rv->serialized_write_fds_length_ = serialized_write_fds_length_; + rv->serialized_message_fds_length_ = serialized_message_fds_length_; rv->serialized_ = true; rv->write_error_ = write_error_; return scoped_refptr<Dispatcher>(rv.get()); @@ -602,6 +679,7 @@ void MessagePipeDispatcher::StartSerializeImplNoLock( !serialized_write_buffer_.empty() || !serialized_message_queue_.empty()) (*max_platform_handles)++; + *max_platform_handles += serialized_fds_.size(); *max_size = sizeof(SerializedMessagePipeHandleDispatcher); } @@ -646,6 +724,20 @@ bool MessagePipeDispatcher::EndSerializeAndCloseImplNoLock( serialization->shared_memory_handle_index = kInvalidMessagePipeHandleIndex; } + serialization->serialized_read_fds_length = serialized_read_fds_length_; + serialization->serialized_write_fds_length = serialized_write_fds_length_; + serialization->serialized_message_fds_length = serialized_message_fds_length_; + if (serialized_fds_.empty()) { + serialization->serialized_fds_index = kInvalidMessagePipeHandleIndex; + } else { +#if defined(OS_POSIX) + serialization->serialized_fds_index = platform_handles->size(); + for (size_t i = 0; i < serialized_fds_.size(); ++i) + platform_handles->push_back(PlatformHandle(serialized_fds_[i])); + serialized_fds_.clear(); +#endif + } + *actual_size = sizeof(SerializedMessagePipeHandleDispatcher); return true; } diff --git a/mojo/edk/system/message_pipe_dispatcher.h b/mojo/edk/system/message_pipe_dispatcher.h index 03c3137..02b66e4 100644 --- a/mojo/edk/system/message_pipe_dispatcher.h +++ b/mojo/edk/system/message_pipe_dispatcher.h @@ -44,7 +44,9 @@ class MOJO_SYSTEM_IMPL_EXPORT MessagePipeDispatcher final void Init( ScopedPlatformHandle message_pipe, char* serialized_read_buffer, size_t serialized_read_buffer_size, - char* serialized_write_buffer, size_t serialized_write_buffer_size); + char* serialized_write_buffer, size_t serialized_write_buffer_size, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds); // |Dispatcher| public methods: Type GetType() const override; @@ -121,11 +123,15 @@ class MOJO_SYSTEM_IMPL_EXPORT MessagePipeDispatcher final MessageInTransitQueue message_queue_; // When sending MP, contains serialized message_queue_. bool serialized_; - // TODO(jam): stop using this and use shared memory instead since we are - // limited to 10K. std::vector<char> serialized_message_queue_; std::vector<char> serialized_read_buffer_; std::vector<char> serialized_write_buffer_; + // Contains FDs from (in this order): the read buffer, the write buffer, and + // message queue. + std::vector<int> serialized_fds_; + size_t serialized_read_fds_length_; + size_t serialized_write_fds_length_; + size_t serialized_message_fds_length_; ScopedPlatformHandle serialized_platform_handle_; AwakableList awakable_list_; diff --git a/mojo/edk/system/raw_channel.cc b/mojo/edk/system/raw_channel.cc index 63576b7..6f560d6 100644 --- a/mojo/edk/system/raw_channel.cc +++ b/mojo/edk/system/raw_channel.cc @@ -303,6 +303,8 @@ void RawChannel::Shutdown() { ScopedPlatformHandle RawChannel::ReleaseHandle( std::vector<char>* serialized_read_buffer, std::vector<char>* serialized_write_buffer, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds, bool* write_error) { ScopedPlatformHandle rv; *write_error = false; @@ -311,6 +313,8 @@ ScopedPlatformHandle RawChannel::ReleaseHandle( base::AutoLock locker(write_lock_); rv = ReleaseHandleNoLock(serialized_read_buffer, serialized_write_buffer, + serialized_read_fds, + serialized_write_fds, write_error); delegate_ = nullptr; internal::g_io_thread_task_runner->PostTask( @@ -364,9 +368,15 @@ bool RawChannel::SendQueuedMessagesNoLock() { void RawChannel::SetSerializedData( char* serialized_read_buffer, size_t serialized_read_buffer_size, - char* serialized_write_buffer, size_t serialized_write_buffer_size) { + char* serialized_write_buffer, size_t serialized_write_buffer_size, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds) { base::AutoLock locker(read_lock_); +#if defined(OS_POSIX) + SetSerializedFDs(serialized_read_fds, serialized_write_fds); +#endif + if (serialized_read_buffer_size) { // TODO(jam): copy power of 2 algorithm below? or share. read_buffer_->buffer_.resize(serialized_read_buffer_size + kReadSize); @@ -490,7 +500,8 @@ void RawChannel::SerializeReadBuffer(size_t additional_bytes_read, void RawChannel::SerializeWriteBuffer( size_t additional_bytes_written, size_t additional_platform_handles_written, - std::vector<char>* buffer) { + std::vector<char>* buffer, + std::vector<int>* fds) { write_lock_.AssertAcquired(); if (write_buffer_->IsEmpty()) { DCHECK_EQ(0u, additional_bytes_written); @@ -501,7 +512,7 @@ void RawChannel::SerializeWriteBuffer( UpdateWriteBuffer( additional_platform_handles_written, additional_bytes_written); while (!write_buffer_->message_queue_.IsEmpty()) { - SerializePlatformHandles(); + SerializePlatformHandles(fds); std::vector<WriteBuffer::Buffer> buffers; write_buffer_no_lock()->GetBuffers(&buffers); for (size_t i = 0; i < buffers.size(); ++i) { diff --git a/mojo/edk/system/raw_channel.h b/mojo/edk/system/raw_channel.h index 6efb211..07b7881 100644 --- a/mojo/edk/system/raw_channel.h +++ b/mojo/edk/system/raw_channel.h @@ -108,7 +108,11 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { // |serialized_read_buffer| contains partially read data, if any. // |serialized_write_buffer| contains a serialized representation of messages // that haven't been written yet. - // Both these arrays need to be passed to SetSerializedData below when + // |serialized_read_fds| is only used on POSIX, and it returns FDs associated + // with partially read data. + // |serialized_write_fds| is only used on POSIX, and it returns FDs associated + // with messages that haven't been written yet. + // All these arrays need to be passed to SetSerializedData below when // recreating the channel. // If there was a read or write in progress, they will be completed. If the // in-progress read results in an error, an invalid handle is returned. If the @@ -118,6 +122,8 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { ScopedPlatformHandle ReleaseHandle( std::vector<char>* serialized_read_buffer, std::vector<char>* serialized_write_buffer, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds, bool* write_error); // Writes the given message (or schedules it to be written). |message| must @@ -132,7 +138,9 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { // ReleaseHandle returns another handle that is shared memory? void SetSerializedData( char* serialized_read_buffer, size_t serialized_read_buffer_size, - char* serialized_write_buffer, size_t serialized_write_buffer_size); + char* serialized_write_buffer, size_t serialized_write_buffer_size, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds); // Checks if this RawChannel is the other endpoint to |other|. bool IsOtherEndOf(RawChannel* other); @@ -255,7 +263,8 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { // buffer so that it can be sent to another process. void SerializeWriteBuffer(size_t additional_bytes_written, size_t additional_platform_handles_written, - std::vector<char>* buffer); + std::vector<char>* buffer, + std::vector<int>* fds); base::Lock& write_lock() { return write_lock_; } base::Lock& read_lock() { return read_lock_; } @@ -285,6 +294,13 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { virtual bool OnReadMessageForRawChannel( const MessageInTransit::View& message_view); +#if defined(OS_POSIX) + // This is used to give the POSIX implementation FDs that belong to ReadBuffer + // and WriteBuffer after the channel is deserialized. + virtual void SetSerializedFDs(std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds) = 0; +#endif + // Returns true iff the pipe handle is valid. virtual bool IsHandleValid() = 0; @@ -292,6 +308,8 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { virtual ScopedPlatformHandle ReleaseHandleNoLock( std::vector<char>* serialized_read_buffer, std::vector<char>* serialized_write_buffer, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds, bool* write_error) = 0; // Reads into |read_buffer()|. @@ -320,14 +338,11 @@ class MOJO_SYSTEM_IMPL_EXPORT RawChannel { size_t num_platform_handles, const void* platform_handle_table) = 0; - // Serialize all platform handles for the front mesasge in the queue from the - // transport data to the transport buffer. - // TODO(jam): once this uses the Master interface to exchange platform handles - // with tokens, it needs to be used when serializing a RawChannel even on - // POSIX. That is because there's no guarantee that we can write pending fds - // when calling ReleaseHandle (because the other side might not be writable - // indefinitely). - virtual size_t SerializePlatformHandles() = 0; + // Serialize all platform handles for the front message in the queue from the + // transport data to the transport buffer. Returns how many handles were + // serialized. + // On POSIX, |fds| contains FDs from the front messages, if any. + virtual size_t SerializePlatformHandles(std::vector<int>* fds) = 0; // Writes contents in |write_buffer_no_lock()|. // This class guarantees that: diff --git a/mojo/edk/system/raw_channel_posix.cc b/mojo/edk/system/raw_channel_posix.cc index 210f3d4..e6627d6 100644 --- a/mojo/edk/system/raw_channel_posix.cc +++ b/mojo/edk/system/raw_channel_posix.cc @@ -5,7 +5,9 @@ #include "mojo/edk/system/raw_channel.h" #include <errno.h> +#include <sys/socket.h> #include <sys/stat.h> +#include <sys/types.h> #include <sys/uio.h> #include <unistd.h> @@ -26,6 +28,10 @@ #include "mojo/edk/system/transport_data.h" #include "mojo/public/cpp/system/macros.h" +#if !defined(SO_PEEK_OFF) +#define SO_PEEK_OFF 42 +#endif + namespace mojo { namespace edk { @@ -51,14 +57,18 @@ class RawChannelPosix final : public RawChannel, ScopedPlatformHandle ReleaseHandleNoLock( std::vector<char>* serialized_read_buffer, std::vector<char>* serialized_write_buffer, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds, bool* write_error) override; + void SetSerializedFDs(std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds) override; bool IsHandleValid() override; IOResult Read(size_t* bytes_read) override; IOResult ScheduleRead() override; ScopedPlatformHandleVectorPtr GetReadPlatformHandles( size_t num_platform_handles, const void* platform_handle_table) override; - size_t SerializePlatformHandles() override; + size_t SerializePlatformHandles(std::vector<int>* fds) override; IOResult WriteNoLock(size_t* platform_handles_written, size_t* bytes_written) override; IOResult ScheduleWriteNoLock() override; @@ -172,11 +182,50 @@ bool RawChannelPosix::OnReadMessageForRawChannel( ScopedPlatformHandle RawChannelPosix::ReleaseHandleNoLock( std::vector<char>* serialized_read_buffer, std::vector<char>* serialized_write_buffer, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds, bool* write_error) { - NOTREACHED() << "TODO(jam) IMPLEMENT"; + read_watcher_.reset(); + write_watcher_.reset(); + + SerializeReadBuffer(0u, serialized_read_buffer); + SerializeWriteBuffer(0u, 0u, serialized_write_buffer, serialized_write_fds); + + while (!read_platform_handles_.empty()) { + serialized_read_fds->push_back(read_platform_handles_.front().fd); + read_platform_handles_.pop_front(); + } + return fd_.Pass(); } +void RawChannelPosix::SetSerializedFDs( + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds) { + if (serialized_read_fds) { + for(auto i: *serialized_read_fds) + read_platform_handles_.push_back(PlatformHandle(i)); + } + + if (serialized_write_fds) { + size_t i = 0; + while (i < serialized_write_fds->size()) { + size_t batch = std::min(kPlatformChannelMaxNumHandles, + serialized_write_fds->size() - i); + scoped_ptr<MessageInTransit> fd_message(new MessageInTransit( + MessageInTransit::Type::RAW_CHANNEL_POSIX_EXTRA_PLATFORM_HANDLES, 0, + nullptr)); + ScopedPlatformHandleVectorPtr fds( + new PlatformHandleVector(serialized_write_fds->begin() + i, + serialized_write_fds->begin() + i + batch)); + fd_message->SetTransportData(make_scoped_ptr( + new TransportData(fds.Pass(), GetSerializedPlatformHandleSize()))); + RawChannel::EnqueueMessageNoLock(fd_message.Pass()); + i += batch; + } + } +} + bool RawChannelPosix::IsHandleValid() { return fd_.is_valid(); } @@ -223,9 +272,20 @@ ScopedPlatformHandleVectorPtr RawChannelPosix::GetReadPlatformHandles( return rv.Pass(); } -size_t RawChannelPosix::SerializePlatformHandles() { - NOTREACHED() << "TODO(jam): implement"; - return 0u; +size_t RawChannelPosix::SerializePlatformHandles(std::vector<int>* fds) { + if (!write_buffer_no_lock()->HavePlatformHandlesToSend()) + return 0u; + + size_t num_platform_handles; + PlatformHandle* platform_handles; + void* serialization_data; // Actually unused. + write_buffer_no_lock()->GetPlatformHandlesToSend( + &num_platform_handles, &platform_handles, &serialization_data); + DCHECK_GT(num_platform_handles, 0u); + DCHECK_LE(num_platform_handles, kPlatformChannelMaxNumHandles); + for (size_t i = 0; i < num_platform_handles; ++i) + fds->push_back(platform_handles[i].fd); + return num_platform_handles; } RawChannel::IOResult RawChannelPosix::WriteNoLock( @@ -330,6 +390,11 @@ RawChannel::IOResult RawChannelPosix::ScheduleWriteNoLock() { void RawChannelPosix::OnInit() { DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); + if (!fd_.is_valid()) { + DVLOG(1) << "Note: RawChannelPOSIX " << this << " early exiting in OnInit " + << "because there's no fd. This is valid if it's been sent."; + return; + } DCHECK(!read_watcher_); read_watcher_.reset(new base::MessageLoopForIO::FileDescriptorWatcher()); @@ -356,15 +421,18 @@ void RawChannelPosix::OnShutdownNoLock( pending_read_ = false; pending_write_ = false; - DCHECK(fd_.is_valid()); fd_.reset(); weak_ptr_factory_.InvalidateWeakPtrs(); } void RawChannelPosix::OnFileCanReadWithoutBlocking(int fd) { - DCHECK_EQ(fd, fd_.get().fd); DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); + base::AutoLock locker(read_lock()); + if (!fd_.is_valid()) { + pending_read_ = false; + return; // ReleaseHandle has been called. + } if (!pending_read_) { NOTREACHED(); @@ -375,7 +443,6 @@ void RawChannelPosix::OnFileCanReadWithoutBlocking(int fd) { size_t bytes_read = 0; IOResult io_result = Read(&bytes_read); if (io_result != IO_PENDING) { - base::AutoLock locker(read_lock()); OnReadCompletedNoLock(io_result, bytes_read); // TODO(vtl): If we weren't destroyed, we'd like to do // @@ -395,8 +462,12 @@ void RawChannelPosix::OnFileCanReadWithoutBlocking(int fd) { } void RawChannelPosix::OnFileCanWriteWithoutBlocking(int fd) { - DCHECK_EQ(fd, fd_.get().fd); DCHECK(internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()); + base::AutoLock locker(read_lock()); + if (!fd_.is_valid()) { + pending_write_ = false; + return; // ReleaseHandle has been called. + } IOResult io_result; size_t platform_handles_written = 0; @@ -499,12 +570,15 @@ bool RawChannel::IsOtherEndOf(RawChannel* other) { PlatformHandle this_handle = static_cast<RawChannelPosix*>(this)->GetFD(); PlatformHandle other_handle = static_cast<RawChannelPosix*>(other)->GetFD(); - struct stat stat1, stat2; - if (fstat(this_handle.fd, &stat1) < 0) - return false; - if (fstat(other_handle.fd, &stat2) < 0) - return false; - return (stat1.st_dev == stat2.st_dev) && (stat1.st_ino == stat2.st_ino); + // We don't check the return code of getsockopt because this is only available + // on Linux after 3.4. This is a developer error, so we just have to catch it + // on platforms that developers use. + int id1 = 0; + int id2 = 1; + socklen_t peek_off_size = sizeof(id1); + getsockopt(this_handle.fd, SOL_SOCKET, SO_PEEK_OFF, &id1, &peek_off_size); + getsockopt(other_handle.fd, SOL_SOCKET, SO_PEEK_OFF, &id2, &peek_off_size); + return id1 == id2; } } // namespace edk diff --git a/mojo/edk/system/raw_channel_win.cc b/mojo/edk/system/raw_channel_win.cc index f4f013a..3063ebe 100644 --- a/mojo/edk/system/raw_channel_win.cc +++ b/mojo/edk/system/raw_channel_win.cc @@ -305,7 +305,7 @@ class RawChannelWin final : public RawChannel { if (!*write_error) { owner_->SerializeWriteBuffer( additional_bytes_written, additional_platform_handles_written, - serialized_write_buffer); + serialized_write_buffer, nullptr); } return ScopedPlatformHandle(handle_.release()); @@ -508,6 +508,8 @@ class RawChannelWin final : public RawChannel { ScopedPlatformHandle ReleaseHandleNoLock( std::vector<char>* serialized_read_buffer, std::vector<char>* serialized_write_buffer, + std::vector<int>* serialized_read_fds, + std::vector<int>* serialized_write_fds, bool* write_error) override { if (handle_.is_valid()) { // SetInitialBuffer could have been called on main thread before OnInit @@ -515,7 +517,7 @@ class RawChannelWin final : public RawChannel { SerializeReadBuffer(0u, serialized_read_buffer); // We could have been given messages to write before OnInit. - SerializeWriteBuffer(0u, 0u, serialized_write_buffer); + SerializeWriteBuffer(0u, 0u, serialized_write_buffer, nullptr); return handle_.Pass(); } @@ -610,7 +612,7 @@ class RawChannelWin final : public RawChannel { return rv.Pass(); } - size_t SerializePlatformHandles() override { + size_t SerializePlatformHandles(std::vector<int>* fds) override { if (!write_buffer_no_lock()->HavePlatformHandlesToSend()) return 0u; @@ -644,7 +646,7 @@ class RawChannelWin final : public RawChannel { DCHECK(io_handler_); DCHECK(!io_handler_->pending_write_no_lock()); - size_t num_platform_handles = SerializePlatformHandles(); + size_t num_platform_handles = SerializePlatformHandles(nullptr); std::vector<WriteBuffer::Buffer> buffers; write_buffer_no_lock()->GetBuffers(&buffers); diff --git a/mojo/edk/system/transport_data.cc b/mojo/edk/system/transport_data.cc index d751511..4f92f95 100644 --- a/mojo/edk/system/transport_data.cc +++ b/mojo/edk/system/transport_data.cc @@ -25,8 +25,6 @@ static_assert(kMaxSizePerPlatformHandle % MessageInTransit::kMessageAlignment == MOJO_STATIC_CONST_MEMBER_DEFINITION const size_t TransportData::kMaxSerializedDispatcherSize; -MOJO_STATIC_CONST_MEMBER_DEFINITION const size_t - TransportData::kMaxSerializedDispatcherPlatformHandles; // static size_t TransportData::GetMaxBufferSize() { @@ -40,8 +38,7 @@ size_t TransportData::GetMaxBufferSize() { // static size_t TransportData::GetMaxPlatformHandles() { - return GetConfiguration().max_message_num_handles * - kMaxSerializedDispatcherPlatformHandles; + return GetConfiguration().max_message_num_handles; } struct TransportData::PrivateStructForCompileAsserts { @@ -89,9 +86,11 @@ TransportData::TransportData(scoped_ptr<DispatcherVector> dispatchers) estimated_size += MessageInTransit::RoundUpMessageAlignment(max_size); DCHECK_LE(estimated_size, GetMaxBufferSize()); - DCHECK_LE(max_platform_handles, kMaxSerializedDispatcherPlatformHandles); estimated_num_platform_handles += max_platform_handles; - DCHECK_LE(estimated_num_platform_handles, GetMaxPlatformHandles()); + // We don't expect more than 10K Mojo handles in one process at a time, + // since each is backed by a FD. If we're hitting the check below, we have + // bigger problems of reducing the number of FDs or possibly multiplexing. + CHECK_LE(estimated_num_platform_handles, GetMaxPlatformHandles()); #if DCHECK_IS_ON() all_max_sizes[i] = max_size; @@ -238,9 +237,7 @@ const char* TransportData::ValidateBuffer( "present"; } } else { - if (header->num_platform_handles > - GetConfiguration().max_message_num_handles * - kMaxSerializedDispatcherPlatformHandles) + if (header->num_platform_handles > GetMaxPlatformHandles()) return "Message has too many platform handles attached"; static const char kInvalidPlatformHandleTableOffset[] = diff --git a/mojo/edk/system/transport_data.h b/mojo/edk/system/transport_data.h index 7d51ee9..16d8d01 100644 --- a/mojo/edk/system/transport_data.h +++ b/mojo/edk/system/transport_data.h @@ -77,10 +77,6 @@ class MOJO_SYSTEM_IMPL_EXPORT TransportData { // of |kMessageAlignment|. static const size_t kMaxSerializedDispatcherSize = 10000; - // The maximum number of platform handles to attach for a single serialized - // dispatcher. - static const size_t kMaxSerializedDispatcherPlatformHandles = 2; - // The maximum possible size of a valid transport data buffer. static size_t GetMaxBufferSize(); diff --git a/mojo/runner/linux_sandbox.cc b/mojo/runner/linux_sandbox.cc index 6990f0a..1318b72 100644 --- a/mojo/runner/linux_sandbox.cc +++ b/mojo/runner/linux_sandbox.cc @@ -84,6 +84,8 @@ class SandboxPolicy : public sandbox::BaselinePolicy { case __NR_ftruncate: case __NR_getrlimit: case __NR_uname: + case __NR_getsockopt: + case __NR_setsockopt: return sandbox::bpf_dsl::Allow(); } |