| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "mojo/edk/embedder/embedder.h" | 5 #include "mojo/edk/embedder/embedder.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 namespace edk { | 27 namespace edk { |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 const MojoHandleSignals kSignalReadadableWritable = | 30 const MojoHandleSignals kSignalReadadableWritable = |
| 31 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; | 31 MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE; |
| 32 | 32 |
| 33 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | | 33 const MojoHandleSignals kSignalAll = MOJO_HANDLE_SIGNAL_READABLE | |
| 34 MOJO_HANDLE_SIGNAL_WRITABLE | | 34 MOJO_HANDLE_SIGNAL_WRITABLE | |
| 35 MOJO_HANDLE_SIGNAL_PEER_CLOSED; | 35 MOJO_HANDLE_SIGNAL_PEER_CLOSED; |
| 36 | 36 |
| 37 class EmbedderTest : public test::MojoSystemTest { | 37 typedef testing::Test EmbedderTest; |
| 38 public: | |
| 39 EmbedderTest() {} | |
| 40 ~EmbedderTest() override {} | |
| 41 | |
| 42 private: | |
| 43 MOJO_DISALLOW_COPY_AND_ASSIGN(EmbedderTest); | |
| 44 }; | |
| 45 | 38 |
| 46 TEST_F(EmbedderTest, ChannelBasic) { | 39 TEST_F(EmbedderTest, ChannelBasic) { |
| 47 MojoHandle server_mp, client_mp; | 40 MojoHandle server_mp, client_mp; |
| 48 ASSERT_EQ(MOJO_RESULT_OK, | 41 ASSERT_EQ(MOJO_RESULT_OK, |
| 49 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); | 42 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); |
| 50 | 43 |
| 51 // We can write to a message pipe handle immediately. | 44 // We can write to a message pipe handle immediately. |
| 52 const char kHello[] = "hello"; | 45 const char kHello[] = "hello"; |
| 53 | 46 |
| 54 size_t write_size = sizeof(kHello); | 47 size_t write_size = sizeof(kHello); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 78 } | 71 } |
| 79 | 72 |
| 80 // Test sending a MP which has read messages out of the OS pipe but which have | 73 // Test sending a MP which has read messages out of the OS pipe but which have |
| 81 // not been consumed using MojoReadMessage yet. | 74 // not been consumed using MojoReadMessage yet. |
| 82 TEST_F(EmbedderTest, SendReadableMessagePipe) { | 75 TEST_F(EmbedderTest, SendReadableMessagePipe) { |
| 83 MojoHandle server_mp, client_mp; | 76 MojoHandle server_mp, client_mp; |
| 84 ASSERT_EQ(MOJO_RESULT_OK, | 77 ASSERT_EQ(MOJO_RESULT_OK, |
| 85 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); | 78 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); |
| 86 | 79 |
| 87 MojoHandle server_mp2, client_mp2; | 80 MojoHandle server_mp2, client_mp2; |
| 81 MojoCreateMessagePipeOptions options; |
| 82 options.struct_size = sizeof(MojoCreateMessagePipeOptions); |
| 83 options.flags = MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE; |
| 88 ASSERT_EQ(MOJO_RESULT_OK, | 84 ASSERT_EQ(MOJO_RESULT_OK, |
| 89 MojoCreateMessagePipe(nullptr, &server_mp2, &client_mp2)); | 85 MojoCreateMessagePipe(&options, &server_mp2, &client_mp2)); |
| 90 | 86 |
| 91 // Write to server2 and wait for client2 to be readable before sending it. | 87 // Write to server2 and wait for client2 to be readable before sending it. |
| 92 // client2's MessagePipeDispatcher will have the message below in its | 88 // client2's MessagePipeDispatcher will have the message below in its |
| 93 // message_queue_. For extra measures, also verify that this pending message | 89 // message_queue_. For extra measures, also verify that this pending message |
| 94 // can contain a message pipe. | 90 // can contain a message pipe. |
| 95 MojoHandle server_mp3, client_mp3; | 91 MojoHandle server_mp3, client_mp3; |
| 96 ASSERT_EQ(MOJO_RESULT_OK, | 92 ASSERT_EQ(MOJO_RESULT_OK, |
| 97 MojoCreateMessagePipe(nullptr, &server_mp3, &client_mp3)); | 93 MojoCreateMessagePipe(nullptr, &server_mp3, &client_mp3)); |
| 98 const char kHello[] = "hello"; | 94 const char kHello[] = "hello"; |
| 99 size_t write_size; | 95 size_t write_size; |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 154 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); |
| 159 } | 155 } |
| 160 | 156 |
| 161 // Verifies that a MP with pending messages to be written can be sent and the | 157 // Verifies that a MP with pending messages to be written can be sent and the |
| 162 // pending messages aren't dropped. | 158 // pending messages aren't dropped. |
| 163 TEST_F(EmbedderTest, SendMessagePipeWithWriteQueue) { | 159 TEST_F(EmbedderTest, SendMessagePipeWithWriteQueue) { |
| 164 MojoHandle server_mp, client_mp; | 160 MojoHandle server_mp, client_mp; |
| 165 ASSERT_EQ(MOJO_RESULT_OK, | 161 ASSERT_EQ(MOJO_RESULT_OK, |
| 166 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); | 162 MojoCreateMessagePipe(nullptr, &server_mp, &client_mp)); |
| 167 | 163 |
| 164 MojoCreateMessagePipeOptions options; |
| 165 options.struct_size = sizeof(MojoCreateMessagePipeOptions); |
| 166 options.flags = MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_TRANSFERABLE; |
| 168 MojoHandle server_mp2, client_mp2; | 167 MojoHandle server_mp2, client_mp2; |
| 169 ASSERT_EQ(MOJO_RESULT_OK, | 168 ASSERT_EQ(MOJO_RESULT_OK, |
| 170 MojoCreateMessagePipe(nullptr, &server_mp2, &client_mp2)); | 169 MojoCreateMessagePipe(&options, &server_mp2, &client_mp2)); |
| 171 | 170 |
| 172 static const size_t kNumMessages = 1001; | 171 static const size_t kNumMessages = 1001; |
| 173 for (size_t i = 0; i < kNumMessages; i++) { | 172 for (size_t i = 0; i < kNumMessages; i++) { |
| 174 std::string write_buffer(i, 'A' + (i % 26)); | 173 std::string write_buffer(i, 'A' + (i % 26)); |
| 175 ASSERT_EQ(MOJO_RESULT_OK, | 174 ASSERT_EQ(MOJO_RESULT_OK, |
| 176 MojoWriteMessage(client_mp2, write_buffer.data(), | 175 MojoWriteMessage(client_mp2, write_buffer.data(), |
| 177 static_cast<uint32_t>(write_buffer.size()), | 176 static_cast<uint32_t>(write_buffer.size()), |
| 178 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | 177 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 179 } | 178 } |
| 180 | 179 |
| (...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals); | 457 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfied_signals); |
| 459 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfiable_signals); | 458 ASSERT_EQ(MOJO_HANDLE_SIGNAL_NONE, state.satisfiable_signals); |
| 460 #endif | 459 #endif |
| 461 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp2)); | 460 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp2)); |
| 462 } | 461 } |
| 463 | 462 |
| 464 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown()); | 463 EXPECT_TRUE(multiprocess_test_helper.WaitForChildTestShutdown()); |
| 465 } | 464 } |
| 466 | 465 |
| 467 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { | 466 MOJO_MULTIPROCESS_TEST_CHILD_TEST(MultiprocessChannelsClient) { |
| 468 base::MessageLoop message_loop; | |
| 469 ScopedPlatformHandle client_platform_handle = | 467 ScopedPlatformHandle client_platform_handle = |
| 470 test::MultiprocessTestHelper::client_platform_handle.Pass(); | 468 test::MultiprocessTestHelper::client_platform_handle.Pass(); |
| 471 EXPECT_TRUE(client_platform_handle.is_valid()); | 469 EXPECT_TRUE(client_platform_handle.is_valid()); |
| 472 | 470 |
| 473 base::TestIOThread test_io_thread(base::TestIOThread::kAutoStart); | 471 MojoHandle client_mp = CreateMessagePipe( |
| 472 client_platform_handle.Pass()).release().value(); |
| 474 | 473 |
| 475 { | 474 // 1. Read the first message from |client_mp|. |
| 476 test::ScopedIPCSupport ipc_support(test_io_thread.task_runner()); | 475 MojoHandleSignalsState state; |
| 477 MojoHandle client_mp = CreateMessagePipe( | 476 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, |
| 478 client_platform_handle.Pass()).release().value(); | 477 MOJO_DEADLINE_INDEFINITE, &state)); |
| 478 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); |
| 479 ASSERT_EQ(kSignalAll, state.satisfiable_signals); |
| 479 | 480 |
| 480 // 1. Read the first message from |client_mp|. | 481 char buffer[1000] = {}; |
| 481 MojoHandleSignalsState state; | 482 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); |
| 482 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | 483 ASSERT_EQ(MOJO_RESULT_OK, |
| 483 MOJO_DEADLINE_INDEFINITE, &state)); | 484 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr, |
| 484 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | 485 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 485 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | 486 const char kHello[] = "hello"; |
| 487 ASSERT_EQ(sizeof(kHello), num_bytes); |
| 488 EXPECT_STREQ(kHello, buffer); |
| 486 | 489 |
| 487 char buffer[1000] = {}; | 490 // 2. Write a message to |client_mp| (attaching nothing). |
| 488 uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); | 491 const char kWorld[] = "world!"; |
| 489 ASSERT_EQ(MOJO_RESULT_OK, | 492 ASSERT_EQ(MOJO_RESULT_OK, |
| 490 MojoReadMessage(client_mp, buffer, &num_bytes, nullptr, nullptr, | 493 MojoWriteMessage(client_mp, kWorld, |
| 491 MOJO_READ_MESSAGE_FLAG_NONE)); | 494 static_cast<uint32_t>(sizeof(kWorld)), nullptr, |
| 492 const char kHello[] = "hello"; | 495 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 493 ASSERT_EQ(sizeof(kHello), num_bytes); | |
| 494 EXPECT_STREQ(kHello, buffer); | |
| 495 | 496 |
| 496 // 2. Write a message to |client_mp| (attaching nothing). | 497 // 4. Read a message from |client_mp|, which should have |mp1| attached. |
| 497 const char kWorld[] = "world!"; | 498 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, |
| 498 ASSERT_EQ(MOJO_RESULT_OK, | 499 MOJO_DEADLINE_INDEFINITE, &state)); |
| 499 MojoWriteMessage(client_mp, kWorld, | 500 // The other end of the handle may or may not be closed at this point, so we |
| 500 static_cast<uint32_t>(sizeof(kWorld)), nullptr, | 501 // can't test MOJO_HANDLE_SIGNAL_WRITABLE or MOJO_HANDLE_SIGNAL_PEER_CLOSED. |
| 501 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | 502 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, |
| 503 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); |
| 504 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, |
| 505 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE); |
| 506 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd |
| 507 // die (again due to |Channel::HandleLocalError()|). |
| 508 memset(buffer, 0, sizeof(buffer)); |
| 509 num_bytes = static_cast<uint32_t>(sizeof(buffer)); |
| 510 MojoHandle mp1 = MOJO_HANDLE_INVALID; |
| 511 uint32_t num_handles = 1; |
| 512 ASSERT_EQ(MOJO_RESULT_OK, |
| 513 MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles, |
| 514 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 515 const char kBar[] = "Bar"; |
| 516 ASSERT_EQ(sizeof(kBar), num_bytes); |
| 517 EXPECT_STREQ(kBar, buffer); |
| 518 ASSERT_EQ(1u, num_handles); |
| 519 EXPECT_NE(mp1, MOJO_HANDLE_INVALID); |
| 520 // TODO(vtl): If the scope were to end here (and the two handles closed), |
| 521 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling |
| 522 // write errors (assuming the parent had closed the pipe). |
| 502 | 523 |
| 503 // 4. Read a message from |client_mp|, which should have |mp1| attached. | 524 // 6. Close |client_mp|. |
| 504 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(client_mp, MOJO_HANDLE_SIGNAL_READABLE, | 525 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); |
| 505 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 506 // The other end of the handle may or may not be closed at this point, so we | |
| 507 // can't test MOJO_HANDLE_SIGNAL_WRITABLE or MOJO_HANDLE_SIGNAL_PEER_CLOSED. | |
| 508 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, | |
| 509 state.satisfied_signals & MOJO_HANDLE_SIGNAL_READABLE); | |
| 510 ASSERT_EQ(MOJO_HANDLE_SIGNAL_READABLE, | |
| 511 state.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE); | |
| 512 // TODO(vtl): If the scope were to end here (and |client_mp| closed), we'd | |
| 513 // die (again due to |Channel::HandleLocalError()|). | |
| 514 memset(buffer, 0, sizeof(buffer)); | |
| 515 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | |
| 516 MojoHandle mp1 = MOJO_HANDLE_INVALID; | |
| 517 uint32_t num_handles = 1; | |
| 518 ASSERT_EQ(MOJO_RESULT_OK, | |
| 519 MojoReadMessage(client_mp, buffer, &num_bytes, &mp1, &num_handles, | |
| 520 MOJO_READ_MESSAGE_FLAG_NONE)); | |
| 521 const char kBar[] = "Bar"; | |
| 522 ASSERT_EQ(sizeof(kBar), num_bytes); | |
| 523 EXPECT_STREQ(kBar, buffer); | |
| 524 ASSERT_EQ(1u, num_handles); | |
| 525 EXPECT_NE(mp1, MOJO_HANDLE_INVALID); | |
| 526 // TODO(vtl): If the scope were to end here (and the two handles closed), | |
| 527 // we'd die due to |Channel::RunRemoteMessagePipeEndpoint()| not handling | |
| 528 // write errors (assuming the parent had closed the pipe). | |
| 529 | 526 |
| 530 // 6. Close |client_mp|. | 527 // Create a new message pipe (endpoints |mp2| and |mp3|). |
| 531 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(client_mp)); | 528 MojoHandle mp2, mp3; |
| 529 ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3)); |
| 532 | 530 |
| 533 // Create a new message pipe (endpoints |mp2| and |mp3|). | 531 // 7. Write a message to |mp3|. |
| 534 MojoHandle mp2, mp3; | 532 const char kBaz[] = "baz"; |
| 535 ASSERT_EQ(MOJO_RESULT_OK, MojoCreateMessagePipe(nullptr, &mp2, &mp3)); | 533 ASSERT_EQ(MOJO_RESULT_OK, |
| 534 MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)), |
| 535 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 536 | 536 |
| 537 // 7. Write a message to |mp3|. | 537 // 8. Close |mp3|. |
| 538 const char kBaz[] = "baz"; | 538 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp3)); |
| 539 ASSERT_EQ(MOJO_RESULT_OK, | |
| 540 MojoWriteMessage(mp3, kBaz, static_cast<uint32_t>(sizeof(kBaz)), | |
| 541 nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE)); | |
| 542 | 539 |
| 543 // 8. Close |mp3|. | 540 // 9. Write a message to |mp1|, attaching |mp2|. |
| 544 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp3)); | 541 const char kQuux[] = "quux"; |
| 542 ASSERT_EQ(MOJO_RESULT_OK, |
| 543 MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)), |
| 544 &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); |
| 545 mp2 = MOJO_HANDLE_INVALID; |
| 545 | 546 |
| 546 // 9. Write a message to |mp1|, attaching |mp2|. | 547 // 3. Read a message from |mp1|. |
| 547 const char kQuux[] = "quux"; | 548 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, |
| 548 ASSERT_EQ(MOJO_RESULT_OK, | 549 MOJO_DEADLINE_INDEFINITE, &state)); |
| 549 MojoWriteMessage(mp1, kQuux, static_cast<uint32_t>(sizeof(kQuux)), | 550 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); |
| 550 &mp2, 1, MOJO_WRITE_MESSAGE_FLAG_NONE)); | 551 ASSERT_EQ(kSignalAll, state.satisfiable_signals); |
| 551 mp2 = MOJO_HANDLE_INVALID; | |
| 552 | 552 |
| 553 // 3. Read a message from |mp1|. | 553 memset(buffer, 0, sizeof(buffer)); |
| 554 ASSERT_EQ(MOJO_RESULT_OK, MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, | 554 num_bytes = static_cast<uint32_t>(sizeof(buffer)); |
| 555 MOJO_DEADLINE_INDEFINITE, &state)); | 555 ASSERT_EQ(MOJO_RESULT_OK, |
| 556 ASSERT_EQ(kSignalReadadableWritable, state.satisfied_signals); | 556 MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr, |
| 557 ASSERT_EQ(kSignalAll, state.satisfiable_signals); | 557 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 558 const char kFoo[] = "FOO"; |
| 559 ASSERT_EQ(sizeof(kFoo), num_bytes); |
| 560 EXPECT_STREQ(kFoo, buffer); |
| 558 | 561 |
| 559 memset(buffer, 0, sizeof(buffer)); | 562 // 11. Wait on |mp1| (which should eventually fail) and then close it. |
| 560 num_bytes = static_cast<uint32_t>(sizeof(buffer)); | 563 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
| 561 ASSERT_EQ(MOJO_RESULT_OK, | 564 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, |
| 562 MojoReadMessage(mp1, buffer, &num_bytes, nullptr, nullptr, | 565 MOJO_DEADLINE_INDEFINITE, &state)); |
| 563 MOJO_READ_MESSAGE_FLAG_NONE)); | 566 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); |
| 564 const char kFoo[] = "FOO"; | 567 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); |
| 565 ASSERT_EQ(sizeof(kFoo), num_bytes); | 568 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp1)); |
| 566 EXPECT_STREQ(kFoo, buffer); | |
| 567 | |
| 568 // 11. Wait on |mp1| (which should eventually fail) and then close it. | |
| 569 ASSERT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | |
| 570 MojoWait(mp1, MOJO_HANDLE_SIGNAL_READABLE, | |
| 571 MOJO_DEADLINE_INDEFINITE, &state)); | |
| 572 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfied_signals); | |
| 573 ASSERT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, state.satisfiable_signals); | |
| 574 ASSERT_EQ(MOJO_RESULT_OK, MojoClose(mp1)); | |
| 575 } | |
| 576 } | 569 } |
| 577 | 570 |
| 578 // TODO(vtl): Test immediate write & close. | 571 // TODO(vtl): Test immediate write & close. |
| 579 // TODO(vtl): Test broken-connection cases. | 572 // TODO(vtl): Test broken-connection cases. |
| 580 | 573 |
| 581 } // namespace | 574 } // namespace |
| 582 } // namespace edk | 575 } // namespace edk |
| 583 } // namespace mojo | 576 } // namespace mojo |
| OLD | NEW |