| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/system/message_pipe.h" | 5 #include "mojo/system/message_pipe.h" |
| 6 | 6 |
| 7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
| 8 #include "base/threading/platform_thread.h" // For |Sleep()|. | 8 #include "base/threading/platform_thread.h" // For |Sleep()|. |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "mojo/system/waiter.h" | 10 #include "mojo/system/waiter.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 // - when there are no/one/two messages available for that port | 21 // - when there are no/one/two messages available for that port |
| 22 // - with buffer size 0 (and null buffer) -- should get size | 22 // - with buffer size 0 (and null buffer) -- should get size |
| 23 // - with too-small buffer -- should get size | 23 // - with too-small buffer -- should get size |
| 24 // - also verify that buffers aren't modified when/where they shouldn't be | 24 // - also verify that buffers aren't modified when/where they shouldn't be |
| 25 // - writing messages to a port | 25 // - writing messages to a port |
| 26 // - in the obvious scenarios (as above) | 26 // - in the obvious scenarios (as above) |
| 27 // - to a port that's been closed | 27 // - to a port that's been closed |
| 28 // - writing a message to a port, closing the other (would be the source) port, | 28 // - writing a message to a port, closing the other (would be the source) port, |
| 29 // and reading it | 29 // and reading it |
| 30 TEST(MessagePipeTest, Basic) { | 30 TEST(MessagePipeTest, Basic) { |
| 31 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 31 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); |
| 32 | 32 |
| 33 int32_t buffer[2]; | 33 int32_t buffer[2]; |
| 34 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 34 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
| 35 uint32_t buffer_size; | 35 uint32_t buffer_size; |
| 36 | 36 |
| 37 // Nothing to read yet on port 0. | 37 // Nothing to read yet on port 0. |
| 38 buffer[0] = 123; | 38 buffer[0] = 123; |
| 39 buffer[1] = 456; | 39 buffer[1] = 456; |
| 40 buffer_size = kBufferSize; | 40 buffer_size = kBufferSize; |
| 41 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 41 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 UserPointer<void>(buffer), | 227 UserPointer<void>(buffer), |
| 228 MakeUserPointer(&buffer_size), | 228 MakeUserPointer(&buffer_size), |
| 229 0, | 229 0, |
| 230 NULL, | 230 NULL, |
| 231 MOJO_READ_MESSAGE_FLAG_NONE)); | 231 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 232 | 232 |
| 233 mp->Close(1); | 233 mp->Close(1); |
| 234 } | 234 } |
| 235 | 235 |
| 236 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) { | 236 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) { |
| 237 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 237 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); |
| 238 | 238 |
| 239 int32_t buffer[1]; | 239 int32_t buffer[1]; |
| 240 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 240 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
| 241 uint32_t buffer_size; | 241 uint32_t buffer_size; |
| 242 | 242 |
| 243 // Write some messages from port 1 (to port 0). | 243 // Write some messages from port 1 (to port 0). |
| 244 for (int32_t i = 0; i < 5; i++) { | 244 for (int32_t i = 0; i < 5; i++) { |
| 245 buffer[0] = i; | 245 buffer[0] = i; |
| 246 EXPECT_EQ(MOJO_RESULT_OK, | 246 EXPECT_EQ(MOJO_RESULT_OK, |
| 247 mp->WriteMessage(1, | 247 mp->WriteMessage(1, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 261 NULL, | 261 NULL, |
| 262 MOJO_READ_MESSAGE_FLAG_NONE)); | 262 MOJO_READ_MESSAGE_FLAG_NONE)); |
| 263 EXPECT_EQ(kBufferSize, buffer_size); | 263 EXPECT_EQ(kBufferSize, buffer_size); |
| 264 | 264 |
| 265 // Close port 0 first, which should have outstanding (incoming) messages. | 265 // Close port 0 first, which should have outstanding (incoming) messages. |
| 266 mp->Close(0); | 266 mp->Close(0); |
| 267 mp->Close(1); | 267 mp->Close(1); |
| 268 } | 268 } |
| 269 | 269 |
| 270 TEST(MessagePipeTest, DiscardMode) { | 270 TEST(MessagePipeTest, DiscardMode) { |
| 271 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 271 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); |
| 272 | 272 |
| 273 int32_t buffer[2]; | 273 int32_t buffer[2]; |
| 274 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 274 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
| 275 uint32_t buffer_size; | 275 uint32_t buffer_size; |
| 276 | 276 |
| 277 // Write from port 1 (to port 0). | 277 // Write from port 1 (to port 0). |
| 278 buffer[0] = 789012345; | 278 buffer[0] = 789012345; |
| 279 buffer[1] = 0; | 279 buffer[1] = 0; |
| 280 EXPECT_EQ(MOJO_RESULT_OK, | 280 EXPECT_EQ(MOJO_RESULT_OK, |
| 281 mp->WriteMessage(1, | 281 mp->WriteMessage(1, |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 MakeUserPointer(&buffer_size), | 399 MakeUserPointer(&buffer_size), |
| 400 0, | 400 0, |
| 401 NULL, | 401 NULL, |
| 402 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | 402 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); |
| 403 | 403 |
| 404 mp->Close(0); | 404 mp->Close(0); |
| 405 mp->Close(1); | 405 mp->Close(1); |
| 406 } | 406 } |
| 407 | 407 |
| 408 TEST(MessagePipeTest, BasicWaiting) { | 408 TEST(MessagePipeTest, BasicWaiting) { |
| 409 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 409 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); |
| 410 Waiter waiter; | 410 Waiter waiter; |
| 411 HandleSignalsState hss; | 411 HandleSignalsState hss; |
| 412 | 412 |
| 413 int32_t buffer[1]; | 413 int32_t buffer[1]; |
| 414 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 414 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
| 415 uint32_t buffer_size; | 415 uint32_t buffer_size; |
| 416 | 416 |
| 417 // Always writable (until the other port is closed). | 417 // Always writable (until the other port is closed). |
| 418 waiter.Init(); | 418 waiter.Init(); |
| 419 hss = HandleSignalsState(); | 419 hss = HandleSignalsState(); |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 | 531 |
| 532 TEST(MessagePipeTest, ThreadedWaiting) { | 532 TEST(MessagePipeTest, ThreadedWaiting) { |
| 533 int32_t buffer[1]; | 533 int32_t buffer[1]; |
| 534 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 534 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
| 535 | 535 |
| 536 MojoResult result; | 536 MojoResult result; |
| 537 uint32_t context; | 537 uint32_t context; |
| 538 | 538 |
| 539 // Write to wake up waiter waiting for read. | 539 // Write to wake up waiter waiting for read. |
| 540 { | 540 { |
| 541 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 541 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); |
| 542 test::SimpleWaiterThread thread(&result, &context); | 542 test::SimpleWaiterThread thread(&result, &context); |
| 543 | 543 |
| 544 thread.waiter()->Init(); | 544 thread.waiter()->Init(); |
| 545 ASSERT_EQ(MOJO_RESULT_OK, | 545 ASSERT_EQ(MOJO_RESULT_OK, |
| 546 mp->AddWaiter( | 546 mp->AddWaiter( |
| 547 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1, NULL)); | 547 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1, NULL)); |
| 548 thread.Start(); | 548 thread.Start(); |
| 549 | 549 |
| 550 buffer[0] = 123456789; | 550 buffer[0] = 123456789; |
| 551 // Write from port 0 (to port 1), which should wake up the waiter. | 551 // Write from port 0 (to port 1), which should wake up the waiter. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 565 | 565 |
| 566 mp->Close(0); | 566 mp->Close(0); |
| 567 mp->Close(1); | 567 mp->Close(1); |
| 568 } // Joins |thread|. | 568 } // Joins |thread|. |
| 569 // The waiter should have woken up successfully. | 569 // The waiter should have woken up successfully. |
| 570 EXPECT_EQ(MOJO_RESULT_OK, result); | 570 EXPECT_EQ(MOJO_RESULT_OK, result); |
| 571 EXPECT_EQ(1u, context); | 571 EXPECT_EQ(1u, context); |
| 572 | 572 |
| 573 // Close to cancel waiter. | 573 // Close to cancel waiter. |
| 574 { | 574 { |
| 575 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 575 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); |
| 576 test::SimpleWaiterThread thread(&result, &context); | 576 test::SimpleWaiterThread thread(&result, &context); |
| 577 | 577 |
| 578 thread.waiter()->Init(); | 578 thread.waiter()->Init(); |
| 579 ASSERT_EQ(MOJO_RESULT_OK, | 579 ASSERT_EQ(MOJO_RESULT_OK, |
| 580 mp->AddWaiter( | 580 mp->AddWaiter( |
| 581 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 2, NULL)); | 581 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 2, NULL)); |
| 582 thread.Start(); | 582 thread.Start(); |
| 583 | 583 |
| 584 // Close port 1 first -- this should result in the waiter being cancelled. | 584 // Close port 1 first -- this should result in the waiter being cancelled. |
| 585 mp->CancelAllWaiters(1); | 585 mp->CancelAllWaiters(1); |
| 586 mp->Close(1); | 586 mp->Close(1); |
| 587 | 587 |
| 588 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the | 588 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the |
| 589 // |MessagePipe| to remove any waiter. | 589 // |MessagePipe| to remove any waiter. |
| 590 | 590 |
| 591 mp->Close(0); | 591 mp->Close(0); |
| 592 } // Joins |thread|. | 592 } // Joins |thread|. |
| 593 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 593 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
| 594 EXPECT_EQ(2u, context); | 594 EXPECT_EQ(2u, context); |
| 595 | 595 |
| 596 // Close to make waiter un-wake-up-able. | 596 // Close to make waiter un-wake-up-able. |
| 597 { | 597 { |
| 598 scoped_refptr<MessagePipe> mp(new MessagePipe()); | 598 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); |
| 599 test::SimpleWaiterThread thread(&result, &context); | 599 test::SimpleWaiterThread thread(&result, &context); |
| 600 | 600 |
| 601 thread.waiter()->Init(); | 601 thread.waiter()->Init(); |
| 602 ASSERT_EQ(MOJO_RESULT_OK, | 602 ASSERT_EQ(MOJO_RESULT_OK, |
| 603 mp->AddWaiter( | 603 mp->AddWaiter( |
| 604 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3, NULL)); | 604 1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3, NULL)); |
| 605 thread.Start(); | 605 thread.Start(); |
| 606 | 606 |
| 607 // Close port 0 first -- this should wake the waiter up, since port 1 will | 607 // Close port 0 first -- this should wake the waiter up, since port 1 will |
| 608 // never be readable. | 608 // never be readable. |
| 609 mp->CancelAllWaiters(0); | 609 mp->CancelAllWaiters(0); |
| 610 mp->Close(0); | 610 mp->Close(0); |
| 611 | 611 |
| 612 HandleSignalsState hss; | 612 HandleSignalsState hss; |
| 613 mp->RemoveWaiter(1, thread.waiter(), &hss); | 613 mp->RemoveWaiter(1, thread.waiter(), &hss); |
| 614 EXPECT_EQ(0u, hss.satisfied_signals); | 614 EXPECT_EQ(0u, hss.satisfied_signals); |
| 615 EXPECT_EQ(0u, hss.satisfiable_signals); | 615 EXPECT_EQ(0u, hss.satisfiable_signals); |
| 616 | 616 |
| 617 mp->CancelAllWaiters(1); | 617 mp->CancelAllWaiters(1); |
| 618 mp->Close(1); | 618 mp->Close(1); |
| 619 } // Joins |thread|. | 619 } // Joins |thread|. |
| 620 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 620 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
| 621 EXPECT_EQ(3u, context); | 621 EXPECT_EQ(3u, context); |
| 622 } | 622 } |
| 623 | 623 |
| 624 } // namespace | 624 } // namespace |
| 625 } // namespace system | 625 } // namespace system |
| 626 } // namespace mojo | 626 } // namespace mojo |
| OLD | NEW |