123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "mojo/core/core.h"
- #include <stdint.h>
- #include <limits>
- #include "base/bind.h"
- #include "base/threading/platform_thread.h"
- #include "build/build_config.h"
- #include "mojo/core/core_test_base.h"
- #include "mojo/public/cpp/system/wait.h"
- #if BUILDFLAG(IS_WIN)
- #include "base/win/windows_version.h"
- #endif
- namespace mojo {
- namespace core {
- namespace {
- const MojoHandleSignalsState kEmptyMojoHandleSignalsState = {0u, 0u};
- const MojoHandleSignalsState kFullMojoHandleSignalsState = {~0u, ~0u};
- const MojoHandleSignals kAllSignals =
- MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE |
- MOJO_HANDLE_SIGNAL_PEER_CLOSED | MOJO_HANDLE_SIGNAL_PEER_REMOTE |
- MOJO_HANDLE_SIGNAL_QUOTA_EXCEEDED;
- using CoreTest = test::CoreTestBase;
- TEST_F(CoreTest, GetTimeTicksNow) {
- const MojoTimeTicks start = core()->GetTimeTicksNow();
- ASSERT_NE(static_cast<MojoTimeTicks>(0), start)
- << "GetTimeTicksNow should return nonzero value";
- base::PlatformThread::Sleep(base::Milliseconds(15));
- const MojoTimeTicks finish = core()->GetTimeTicksNow();
- // Allow for some fuzz in sleep.
- ASSERT_GE((finish - start), static_cast<MojoTimeTicks>(8000))
- << "Sleeping should result in increasing time ticks";
- }
- TEST_F(CoreTest, Basic) {
- MockHandleInfo info;
- ASSERT_EQ(0u, info.GetCtorCallCount());
- MojoHandle h = CreateMockHandle(&info);
- ASSERT_EQ(1u, info.GetCtorCallCount());
- ASSERT_NE(h, MOJO_HANDLE_INVALID);
- ASSERT_EQ(0u, info.GetWriteMessageCallCount());
- MojoMessageHandle message;
- ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
- ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h, message, nullptr));
- ASSERT_EQ(1u, info.GetWriteMessageCallCount());
- ASSERT_EQ(0u, info.GetReadMessageCallCount());
- ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, &message));
- ASSERT_EQ(1u, info.GetReadMessageCallCount());
- ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h, nullptr, &message));
- ASSERT_EQ(2u, info.GetReadMessageCallCount());
- ASSERT_EQ(0u, info.GetWriteDataCallCount());
- ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
- core()->WriteData(h, nullptr, nullptr, nullptr));
- ASSERT_EQ(1u, info.GetWriteDataCallCount());
- ASSERT_EQ(0u, info.GetBeginWriteDataCallCount());
- ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
- core()->BeginWriteData(h, nullptr, nullptr, nullptr));
- ASSERT_EQ(1u, info.GetBeginWriteDataCallCount());
- ASSERT_EQ(0u, info.GetEndWriteDataCallCount());
- ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndWriteData(h, 0, nullptr));
- ASSERT_EQ(1u, info.GetEndWriteDataCallCount());
- ASSERT_EQ(0u, info.GetReadDataCallCount());
- ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
- core()->ReadData(h, nullptr, nullptr, nullptr));
- ASSERT_EQ(1u, info.GetReadDataCallCount());
- ASSERT_EQ(0u, info.GetBeginReadDataCallCount());
- ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED,
- core()->BeginReadData(h, nullptr, nullptr, nullptr));
- ASSERT_EQ(1u, info.GetBeginReadDataCallCount());
- ASSERT_EQ(0u, info.GetEndReadDataCallCount());
- ASSERT_EQ(MOJO_RESULT_UNIMPLEMENTED, core()->EndReadData(h, 0, nullptr));
- ASSERT_EQ(1u, info.GetEndReadDataCallCount());
- ASSERT_EQ(0u, info.GetDtorCallCount());
- ASSERT_EQ(0u, info.GetCloseCallCount());
- ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
- ASSERT_EQ(1u, info.GetCloseCallCount());
- ASSERT_EQ(1u, info.GetDtorCallCount());
- }
- TEST_F(CoreTest, InvalidArguments) {
- // |Close()|:
- {
- 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);
- 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());
- }
- // |CreateMessagePipe()|: Nothing to check (apart from things that cause
- // death).
- // |WriteMessageNew()|:
- // Only check arguments checked by |Core|, namely |handle|, |handles|, and
- // |num_handles|.
- ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- core()->WriteMessage(MOJO_HANDLE_INVALID, 0, nullptr));
- // |ReadMessageNew()|:
- // Only check arguments checked by |Core|, namely |handle|, |handles|, and
- // |num_handles|.
- {
- ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- core()->ReadMessage(MOJO_HANDLE_INVALID, nullptr, nullptr));
- MockHandleInfo info;
- MojoHandle h = CreateMockHandle(&info);
- ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- core()->ReadMessage(h, nullptr, nullptr));
- // Checked by |Core|, shouldn't go through to the dispatcher.
- ASSERT_EQ(0u, info.GetReadMessageCallCount());
- ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h));
- }
- }
- TEST_F(CoreTest, MessagePipe) {
- MojoHandle h[2];
- MojoHandleSignalsState hss[2];
- ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessagePipe(nullptr, &h[0], &h[1]));
- // Should get two distinct, valid handles.
- ASSERT_NE(h[0], MOJO_HANDLE_INVALID);
- ASSERT_NE(h[1], MOJO_HANDLE_INVALID);
- ASSERT_NE(h[0], h[1]);
- // Neither should be readable.
- hss[0] = kEmptyMojoHandleSignalsState;
- hss[1] = kEmptyMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[0], &hss[0]));
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[1], &hss[1]));
- 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.
- MojoMessageHandle message;
- ASSERT_EQ(MOJO_RESULT_SHOULD_WAIT,
- core()->ReadMessage(h[0], nullptr, &message));
- // Write to |h[1]|.
- const uintptr_t kTestMessageContext = 123;
- ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->SetMessageContext(message, kTestMessageContext, nullptr,
- nullptr, nullptr));
- ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[1], message, nullptr));
- // Wait for |h[0]| to become readable.
- EXPECT_EQ(MOJO_RESULT_OK, mojo::Wait(mojo::Handle(h[0]),
- MOJO_HANDLE_SIGNAL_READABLE, &hss[0]));
- // Read from |h[0]|.
- ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h[0], nullptr, &message));
- uintptr_t context;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->GetMessageContext(message, nullptr, &context));
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->SetMessageContext(message, 0, nullptr, nullptr, nullptr));
- ASSERT_EQ(kTestMessageContext, context);
- ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
- // |h[0]| should no longer be readable.
- hss[0] = kEmptyMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[0], &hss[0]));
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss[0].satisfied_signals);
- ASSERT_EQ(kAllSignals, hss[0].satisfiable_signals);
- // Write to |h[0]|.
- ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->SetMessageContext(message, kTestMessageContext, nullptr,
- nullptr, nullptr));
- ASSERT_EQ(MOJO_RESULT_OK, core()->WriteMessage(h[0], message, nullptr));
- // 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,
- mojo::Wait(mojo::Handle(h[1]), MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss[1]));
- // Check that |h[1]| is no longer writable (and will never be).
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss[1].satisfied_signals);
- EXPECT_FALSE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_WRITABLE);
- // Check that |h[1]| is still readable (for the moment).
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
- hss[1].satisfied_signals);
- EXPECT_TRUE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
- // Discard a message from |h[1]|.
- ASSERT_EQ(MOJO_RESULT_OK, core()->ReadMessage(h[1], nullptr, &message));
- ASSERT_EQ(MOJO_RESULT_OK, core()->DestroyMessage(message));
- // |h[1]| is no longer readable (and will never be).
- hss[1] = kFullMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(h[1], &hss[1]));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss[1].satisfied_signals);
- EXPECT_FALSE(hss[1].satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE);
- // Try writing to |h[1]|.
- ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->SetMessageContext(message, kTestMessageContext, nullptr,
- nullptr, nullptr));
- ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
- core()->WriteMessage(h[1], message, nullptr));
- ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h[1]));
- }
- // Tests passing a message pipe handle.
- TEST_F(CoreTest, MessagePipeBasicLocalHandlePassing1) {
- MojoHandleSignalsState hss;
- MojoHandle h_passing[2];
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->CreateMessagePipe(nullptr, &h_passing[0], &h_passing[1]));
- // Make sure that |h_passing[]| work properly.
- const uintptr_t kTestMessageContext = 42;
- MojoMessageHandle message;
- ASSERT_EQ(MOJO_RESULT_OK, core()->CreateMessage(nullptr, &message));
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->SetMessageContext(message, kTestMessageContext, nullptr,
- nullptr, nullptr));
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->WriteMessage(h_passing[0], message, nullptr));
- hss = kEmptyMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, mojo::Wait(mojo::Handle(h_passing[1]),
- MOJO_HANDLE_SIGNAL_READABLE, &hss));
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
- hss.satisfied_signals);
- ASSERT_EQ(kAllSignals, hss.satisfiable_signals);
- MojoMessageHandle message_handle;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->ReadMessage(h_passing[1], nullptr, &message_handle));
- uintptr_t context;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->GetMessageContext(message_handle, nullptr, &context));
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->SetMessageContext(message, 0, nullptr, nullptr, nullptr));
- ASSERT_EQ(kTestMessageContext, context);
- ASSERT_EQ(MOJO_RESULT_OK, MojoDestroyMessage(message_handle));
- ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[0]));
- ASSERT_EQ(MOJO_RESULT_OK, core()->Close(h_passing[1]));
- }
- TEST_F(CoreTest, DataPipe) {
- MojoHandle ph, ch; // p is for producer and c is for consumer.
- MojoHandleSignalsState hss;
- ASSERT_EQ(MOJO_RESULT_OK, core()->CreateDataPipe(nullptr, &ph, &ch));
- // Should get two distinct, valid handles.
- 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(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ph, &hss));
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
- MOJO_HANDLE_SIGNAL_PEER_REMOTE,
- hss.satisfiable_signals);
- // Consumer should be never-writable, and not yet readable.
- hss = kFullMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
- MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
- MOJO_HANDLE_SIGNAL_PEER_REMOTE,
- hss.satisfiable_signals);
- // Write.
- signed char elements[2] = {'A', 'B'};
- uint32_t num_bytes = 2u;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->WriteData(ph, elements, &num_bytes, nullptr));
- ASSERT_EQ(2u, num_bytes);
- // Wait for the data to arrive to the consumer.
- EXPECT_EQ(MOJO_RESULT_OK,
- mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
- // Consumer should now be readable.
- hss = kEmptyMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE,
- hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
- MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
- MOJO_HANDLE_SIGNAL_PEER_REMOTE,
- hss.satisfiable_signals);
- // Peek one character.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = 1u;
- MojoReadDataOptions read_options;
- read_options.struct_size = sizeof(read_options);
- read_options.flags = MOJO_READ_DATA_FLAG_NONE | MOJO_READ_DATA_FLAG_PEEK;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->ReadData(ch, &read_options, elements, &num_bytes));
- ASSERT_EQ('A', elements[0]);
- ASSERT_EQ(-1, elements[1]);
- // Read one character.
- elements[0] = -1;
- elements[1] = -1;
- num_bytes = 1u;
- read_options.flags = MOJO_READ_DATA_FLAG_NONE;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->ReadData(ch, &read_options, elements, &num_bytes));
- ASSERT_EQ('A', elements[0]);
- ASSERT_EQ(-1, elements[1]);
- // Two-phase write.
- void* write_ptr = nullptr;
- num_bytes = 0u;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->BeginWriteData(ph, nullptr, &write_ptr, &num_bytes));
- // We count on the default options providing a decent buffer size.
- ASSERT_GE(num_bytes, 3u);
- // Trying to do a normal write during a two-phase write should fail.
- elements[0] = 'X';
- num_bytes = 1u;
- ASSERT_EQ(MOJO_RESULT_BUSY,
- core()->WriteData(ph, elements, &num_bytes, nullptr));
- // Actually write the data, and complete it now.
- static_cast<char*>(write_ptr)[0] = 'C';
- static_cast<char*>(write_ptr)[1] = 'D';
- static_cast<char*>(write_ptr)[2] = 'E';
- ASSERT_EQ(MOJO_RESULT_OK, core()->EndWriteData(ph, 3u, nullptr));
- // Wait for the data to arrive to the consumer.
- ASSERT_EQ(MOJO_RESULT_OK,
- mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
- // Query how much data we have.
- num_bytes = 0;
- read_options.flags = MOJO_READ_DATA_FLAG_QUERY;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->ReadData(ch, &read_options, nullptr, &num_bytes));
- ASSERT_GE(num_bytes, 1u);
- // Try to query with peek. Should fail.
- num_bytes = 0;
- read_options.flags = MOJO_READ_DATA_FLAG_QUERY | MOJO_READ_DATA_FLAG_PEEK;
- ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- core()->ReadData(ch, &read_options, nullptr, &num_bytes));
- ASSERT_EQ(0u, num_bytes);
- // Try to discard ten characters, in all-or-none mode. Should fail.
- num_bytes = 10;
- read_options.flags =
- MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE;
- ASSERT_EQ(MOJO_RESULT_OUT_OF_RANGE,
- core()->ReadData(ch, &read_options, nullptr, &num_bytes));
- // Try to discard two characters, in peek mode. Should fail.
- num_bytes = 2;
- read_options.flags = MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_PEEK;
- ASSERT_EQ(MOJO_RESULT_INVALID_ARGUMENT,
- core()->ReadData(ch, &read_options, nullptr, &num_bytes));
- // Discard a character.
- num_bytes = 1;
- read_options.flags =
- MOJO_READ_DATA_FLAG_DISCARD | MOJO_READ_DATA_FLAG_ALL_OR_NONE;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->ReadData(ch, &read_options, nullptr, &num_bytes));
- // Ensure the 3 bytes were read.
- ASSERT_EQ(MOJO_RESULT_OK,
- mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_READABLE, &hss));
- // Read the remaining three characters, in two-phase mode.
- const void* read_ptr = nullptr;
- num_bytes = 3;
- ASSERT_EQ(MOJO_RESULT_OK,
- core()->BeginReadData(ch, nullptr, &read_ptr, &num_bytes));
- // Note: Count on still being able to do the contiguous read here.
- ASSERT_EQ(3u, num_bytes);
- // Discarding right now should fail.
- num_bytes = 1;
- read_options.flags = MOJO_READ_DATA_FLAG_DISCARD;
- ASSERT_EQ(MOJO_RESULT_BUSY,
- core()->ReadData(ch, &read_options, nullptr, &num_bytes));
- // Actually check our data and end the two-phase read.
- 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, nullptr));
- // Consumer should now be no longer readable.
- hss = kFullMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
- EXPECT_EQ(0u, hss.satisfied_signals);
- EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED |
- MOJO_HANDLE_SIGNAL_NEW_DATA_READABLE |
- MOJO_HANDLE_SIGNAL_PEER_REMOTE,
- hss.satisfiable_signals);
- // TODO(vtl): More.
- // Close the producer.
- ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ph));
- // Wait for this to get to the consumer.
- EXPECT_EQ(MOJO_RESULT_OK,
- mojo::Wait(mojo::Handle(ch), MOJO_HANDLE_SIGNAL_PEER_CLOSED, &hss));
- // The consumer should now be never-readable.
- hss = kFullMojoHandleSignalsState;
- EXPECT_EQ(MOJO_RESULT_OK, core()->QueryHandleSignalsState(ch, &hss));
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals);
- ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals);
- ASSERT_EQ(MOJO_RESULT_OK, core()->Close(ch));
- }
- } // namespace
- } // namespace core
- } // namespace mojo
|