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/edk/system/message_pipe.h" | 5 #include "mojo/edk/system/message_pipe.h" |
6 | 6 |
7 #include "base/memory/ref_counted.h" | |
8 #include "mojo/edk/system/waiter.h" | 7 #include "mojo/edk/system/waiter.h" |
9 #include "mojo/edk/system/waiter_test_utils.h" | 8 #include "mojo/edk/system/waiter_test_utils.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
11 | 10 |
12 namespace mojo { | 11 namespace mojo { |
13 namespace system { | 12 namespace system { |
14 namespace { | 13 namespace { |
15 | 14 |
16 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE | | 15 const MojoHandleSignals kAllSignals = MOJO_HANDLE_SIGNAL_READABLE | |
17 MOJO_HANDLE_SIGNAL_WRITABLE | | 16 MOJO_HANDLE_SIGNAL_WRITABLE | |
18 MOJO_HANDLE_SIGNAL_PEER_CLOSED; | 17 MOJO_HANDLE_SIGNAL_PEER_CLOSED; |
19 | 18 |
20 // Tests: | 19 // Tests: |
21 // - only default flags | 20 // - only default flags |
22 // - reading messages from a port | 21 // - reading messages from a port |
23 // - when there are no/one/two messages available for that port | 22 // - when there are no/one/two messages available for that port |
24 // - with buffer size 0 (and null buffer) -- should get size | 23 // - with buffer size 0 (and null buffer) -- should get size |
25 // - with too-small buffer -- should get size | 24 // - with too-small buffer -- should get size |
26 // - also verify that buffers aren't modified when/where they shouldn't be | 25 // - also verify that buffers aren't modified when/where they shouldn't be |
27 // - writing messages to a port | 26 // - writing messages to a port |
28 // - in the obvious scenarios (as above) | 27 // - in the obvious scenarios (as above) |
29 // - to a port that's been closed | 28 // - to a port that's been closed |
30 // - writing a message to a port, closing the other (would be the source) port, | 29 // - writing a message to a port, closing the other (would be the source) port, |
31 // and reading it | 30 // and reading it |
32 TEST(MessagePipeTest, Basic) { | 31 TEST(MessagePipeTest, Basic) { |
33 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 32 auto mp = MessagePipe::CreateLocalLocal(); |
34 | 33 |
35 int32_t buffer[2]; | 34 int32_t buffer[2]; |
36 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 35 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
37 uint32_t buffer_size; | 36 uint32_t buffer_size; |
38 | 37 |
39 // Nothing to read yet on port 0. | 38 // Nothing to read yet on port 0. |
40 buffer[0] = 123; | 39 buffer[0] = 123; |
41 buffer[1] = 456; | 40 buffer[1] = 456; |
42 buffer_size = kBufferSize; | 41 buffer_size = kBufferSize; |
43 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 42 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 buffer_size = kBufferSize; | 184 buffer_size = kBufferSize; |
186 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, | 185 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, |
187 mp->ReadMessage(1, UserPointer<void>(buffer), | 186 mp->ReadMessage(1, UserPointer<void>(buffer), |
188 MakeUserPointer(&buffer_size), 0, nullptr, | 187 MakeUserPointer(&buffer_size), 0, nullptr, |
189 MOJO_READ_MESSAGE_FLAG_NONE)); | 188 MOJO_READ_MESSAGE_FLAG_NONE)); |
190 | 189 |
191 mp->Close(1); | 190 mp->Close(1); |
192 } | 191 } |
193 | 192 |
194 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) { | 193 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) { |
195 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 194 auto mp = MessagePipe::CreateLocalLocal(); |
196 | 195 |
197 int32_t buffer[1]; | 196 int32_t buffer[1]; |
198 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 197 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
199 uint32_t buffer_size; | 198 uint32_t buffer_size; |
200 | 199 |
201 // Write some messages from port 1 (to port 0). | 200 // Write some messages from port 1 (to port 0). |
202 for (int32_t i = 0; i < 5; i++) { | 201 for (int32_t i = 0; i < 5; i++) { |
203 buffer[0] = i; | 202 buffer[0] = i; |
204 EXPECT_EQ(MOJO_RESULT_OK, | 203 EXPECT_EQ(MOJO_RESULT_OK, |
205 mp->WriteMessage(1, UserPointer<const void>(buffer), kBufferSize, | 204 mp->WriteMessage(1, UserPointer<const void>(buffer), kBufferSize, |
206 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); | 205 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); |
207 } | 206 } |
208 | 207 |
209 // Port 0 shouldn't be empty. | 208 // Port 0 shouldn't be empty. |
210 buffer_size = 0; | 209 buffer_size = 0; |
211 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, | 210 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, |
212 mp->ReadMessage(0, NullUserPointer(), MakeUserPointer(&buffer_size), | 211 mp->ReadMessage(0, NullUserPointer(), MakeUserPointer(&buffer_size), |
213 0, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); | 212 0, nullptr, MOJO_READ_MESSAGE_FLAG_NONE)); |
214 EXPECT_EQ(kBufferSize, buffer_size); | 213 EXPECT_EQ(kBufferSize, buffer_size); |
215 | 214 |
216 // Close port 0 first, which should have outstanding (incoming) messages. | 215 // Close port 0 first, which should have outstanding (incoming) messages. |
217 mp->Close(0); | 216 mp->Close(0); |
218 mp->Close(1); | 217 mp->Close(1); |
219 } | 218 } |
220 | 219 |
221 TEST(MessagePipeTest, DiscardMode) { | 220 TEST(MessagePipeTest, DiscardMode) { |
222 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 221 auto mp = MessagePipe::CreateLocalLocal(); |
223 | 222 |
224 int32_t buffer[2]; | 223 int32_t buffer[2]; |
225 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 224 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
226 uint32_t buffer_size; | 225 uint32_t buffer_size; |
227 | 226 |
228 // Write from port 1 (to port 0). | 227 // Write from port 1 (to port 0). |
229 buffer[0] = 789012345; | 228 buffer[0] = 789012345; |
230 buffer[1] = 0; | 229 buffer[1] = 0; |
231 EXPECT_EQ(MOJO_RESULT_OK, | 230 EXPECT_EQ(MOJO_RESULT_OK, |
232 mp->WriteMessage(1, UserPointer<const void>(buffer), | 231 mp->WriteMessage(1, UserPointer<const void>(buffer), |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, | 315 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, |
317 mp->ReadMessage(0, UserPointer<void>(buffer), | 316 mp->ReadMessage(0, UserPointer<void>(buffer), |
318 MakeUserPointer(&buffer_size), 0, nullptr, | 317 MakeUserPointer(&buffer_size), 0, nullptr, |
319 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); | 318 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)); |
320 | 319 |
321 mp->Close(0); | 320 mp->Close(0); |
322 mp->Close(1); | 321 mp->Close(1); |
323 } | 322 } |
324 | 323 |
325 TEST(MessagePipeTest, BasicWaiting) { | 324 TEST(MessagePipeTest, BasicWaiting) { |
326 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 325 auto mp = MessagePipe::CreateLocalLocal(); |
327 Waiter waiter; | 326 Waiter waiter; |
328 HandleSignalsState hss; | 327 HandleSignalsState hss; |
329 | 328 |
330 int32_t buffer[1]; | 329 int32_t buffer[1]; |
331 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 330 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
332 uint32_t buffer_size; | 331 uint32_t buffer_size; |
333 | 332 |
334 // Always writable (until the other port is closed). | 333 // Always writable (until the other port is closed). |
335 waiter.Init(); | 334 waiter.Init(); |
336 hss = HandleSignalsState(); | 335 hss = HandleSignalsState(); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
458 | 457 |
459 TEST(MessagePipeTest, ThreadedWaiting) { | 458 TEST(MessagePipeTest, ThreadedWaiting) { |
460 int32_t buffer[1]; | 459 int32_t buffer[1]; |
461 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); | 460 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); |
462 | 461 |
463 MojoResult result; | 462 MojoResult result; |
464 uint32_t context; | 463 uint32_t context; |
465 | 464 |
466 // Write to wake up waiter waiting for read. | 465 // Write to wake up waiter waiting for read. |
467 { | 466 { |
468 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 467 auto mp = MessagePipe::CreateLocalLocal(); |
469 test::SimpleWaiterThread thread(&result, &context); | 468 test::SimpleWaiterThread thread(&result, &context); |
470 | 469 |
471 thread.waiter()->Init(); | 470 thread.waiter()->Init(); |
472 ASSERT_EQ(MOJO_RESULT_OK, | 471 ASSERT_EQ(MOJO_RESULT_OK, |
473 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, | 472 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, |
474 1, nullptr)); | 473 1, nullptr)); |
475 thread.Start(); | 474 thread.Start(); |
476 | 475 |
477 buffer[0] = 123456789; | 476 buffer[0] = 123456789; |
478 // Write from port 0 (to port 1), which should wake up the waiter. | 477 // Write from port 0 (to port 1), which should wake up the waiter. |
479 EXPECT_EQ(MOJO_RESULT_OK, | 478 EXPECT_EQ(MOJO_RESULT_OK, |
480 mp->WriteMessage(0, UserPointer<const void>(buffer), kBufferSize, | 479 mp->WriteMessage(0, UserPointer<const void>(buffer), kBufferSize, |
481 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); | 480 nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE)); |
482 | 481 |
483 HandleSignalsState hss; | 482 HandleSignalsState hss; |
484 mp->RemoveAwakable(1, thread.waiter(), &hss); | 483 mp->RemoveAwakable(1, thread.waiter(), &hss); |
485 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, | 484 EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, |
486 hss.satisfied_signals); | 485 hss.satisfied_signals); |
487 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); | 486 EXPECT_EQ(kAllSignals, hss.satisfiable_signals); |
488 | 487 |
489 mp->Close(0); | 488 mp->Close(0); |
490 mp->Close(1); | 489 mp->Close(1); |
491 } // Joins |thread|. | 490 } // Joins |thread|. |
492 // The waiter should have woken up successfully. | 491 // The waiter should have woken up successfully. |
493 EXPECT_EQ(MOJO_RESULT_OK, result); | 492 EXPECT_EQ(MOJO_RESULT_OK, result); |
494 EXPECT_EQ(1u, context); | 493 EXPECT_EQ(1u, context); |
495 | 494 |
496 // Close to cancel waiter. | 495 // Close to cancel waiter. |
497 { | 496 { |
498 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 497 auto mp = MessagePipe::CreateLocalLocal(); |
499 test::SimpleWaiterThread thread(&result, &context); | 498 test::SimpleWaiterThread thread(&result, &context); |
500 | 499 |
501 thread.waiter()->Init(); | 500 thread.waiter()->Init(); |
502 ASSERT_EQ(MOJO_RESULT_OK, | 501 ASSERT_EQ(MOJO_RESULT_OK, |
503 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, | 502 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, |
504 2, nullptr)); | 503 2, nullptr)); |
505 thread.Start(); | 504 thread.Start(); |
506 | 505 |
507 // Close port 1 first -- this should result in the waiter being cancelled. | 506 // Close port 1 first -- this should result in the waiter being cancelled. |
508 mp->CancelAllAwakables(1); | 507 mp->CancelAllAwakables(1); |
509 mp->Close(1); | 508 mp->Close(1); |
510 | 509 |
511 // Port 1 is closed, so |Dispatcher::RemoveAwakable()| wouldn't call into | 510 // Port 1 is closed, so |Dispatcher::RemoveAwakable()| wouldn't call into |
512 // the |MessagePipe| to remove any waiter. | 511 // the |MessagePipe| to remove any waiter. |
513 | 512 |
514 mp->Close(0); | 513 mp->Close(0); |
515 } // Joins |thread|. | 514 } // Joins |thread|. |
516 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 515 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
517 EXPECT_EQ(2u, context); | 516 EXPECT_EQ(2u, context); |
518 | 517 |
519 // Close to cancel waiter using peer closed signal. | 518 // Close to cancel waiter using peer closed signal. |
520 { | 519 { |
521 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 520 auto mp = MessagePipe::CreateLocalLocal(); |
522 test::SimpleWaiterThread thread(&result, &context); | 521 test::SimpleWaiterThread thread(&result, &context); |
523 | 522 |
524 thread.waiter()->Init(); | 523 thread.waiter()->Init(); |
525 ASSERT_EQ(MOJO_RESULT_OK, | 524 ASSERT_EQ(MOJO_RESULT_OK, |
526 mp->AddAwakable(1, thread.waiter(), | 525 mp->AddAwakable(1, thread.waiter(), |
527 MOJO_HANDLE_SIGNAL_PEER_CLOSED, 3, nullptr)); | 526 MOJO_HANDLE_SIGNAL_PEER_CLOSED, 3, nullptr)); |
528 thread.Start(); | 527 thread.Start(); |
529 | 528 |
530 // Close port 1 first -- this should result in the waiter being cancelled. | 529 // Close port 1 first -- this should result in the waiter being cancelled. |
531 mp->CancelAllAwakables(1); | 530 mp->CancelAllAwakables(1); |
532 mp->Close(1); | 531 mp->Close(1); |
533 | 532 |
534 // Port 1 is closed, so |Dispatcher::RemoveAwakable()| wouldn't call into | 533 // Port 1 is closed, so |Dispatcher::RemoveAwakable()| wouldn't call into |
535 // the |MessagePipe| to remove any waiter. | 534 // the |MessagePipe| to remove any waiter. |
536 | 535 |
537 mp->Close(0); | 536 mp->Close(0); |
538 } // Joins |thread|. | 537 } // Joins |thread|. |
539 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); | 538 EXPECT_EQ(MOJO_RESULT_CANCELLED, result); |
540 EXPECT_EQ(3u, context); | 539 EXPECT_EQ(3u, context); |
541 | 540 |
542 // Close to make waiter un-wake-up-able. | 541 // Close to make waiter un-wake-up-able. |
543 { | 542 { |
544 scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); | 543 auto mp = MessagePipe::CreateLocalLocal(); |
545 test::SimpleWaiterThread thread(&result, &context); | 544 test::SimpleWaiterThread thread(&result, &context); |
546 | 545 |
547 thread.waiter()->Init(); | 546 thread.waiter()->Init(); |
548 ASSERT_EQ(MOJO_RESULT_OK, | 547 ASSERT_EQ(MOJO_RESULT_OK, |
549 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, | 548 mp->AddAwakable(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, |
550 4, nullptr)); | 549 4, nullptr)); |
551 thread.Start(); | 550 thread.Start(); |
552 | 551 |
553 // Close port 0 first -- this should wake the waiter up, since port 1 will | 552 // Close port 0 first -- this should wake the waiter up, since port 1 will |
554 // never be readable. | 553 // never be readable. |
555 mp->CancelAllAwakables(0); | 554 mp->CancelAllAwakables(0); |
556 mp->Close(0); | 555 mp->Close(0); |
557 | 556 |
558 HandleSignalsState hss; | 557 HandleSignalsState hss; |
559 mp->RemoveAwakable(1, thread.waiter(), &hss); | 558 mp->RemoveAwakable(1, thread.waiter(), &hss); |
560 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals); | 559 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfied_signals); |
561 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); | 560 EXPECT_EQ(MOJO_HANDLE_SIGNAL_PEER_CLOSED, hss.satisfiable_signals); |
562 | 561 |
563 mp->CancelAllAwakables(1); | 562 mp->CancelAllAwakables(1); |
564 mp->Close(1); | 563 mp->Close(1); |
565 } // Joins |thread|. | 564 } // Joins |thread|. |
566 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); | 565 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); |
567 EXPECT_EQ(4u, context); | 566 EXPECT_EQ(4u, context); |
568 } | 567 } |
569 | 568 |
570 } // namespace | 569 } // namespace |
571 } // namespace system | 570 } // namespace system |
572 } // namespace mojo | 571 } // namespace mojo |
OLD | NEW |