| 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/system/raw_channel.h" | 5 #include "mojo/system/raw_channel.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/compiler_specific.h" | |
| 13 #include "base/location.h" | 12 #include "base/location.h" |
| 14 #include "base/logging.h" | 13 #include "base/logging.h" |
| 15 #include "base/macros.h" | 14 #include "base/macros.h" |
| 16 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 17 #include "base/memory/scoped_vector.h" | 16 #include "base/memory/scoped_vector.h" |
| 18 #include "base/rand_util.h" | 17 #include "base/rand_util.h" |
| 19 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
| 20 #include "base/synchronization/waitable_event.h" | 19 #include "base/synchronization/waitable_event.h" |
| 21 #include "base/threading/platform_thread.h" // For |Sleep()|. | 20 #include "base/threading/platform_thread.h" // For |Sleep()|. |
| 22 #include "base/threading/simple_thread.h" | 21 #include "base/threading/simple_thread.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 46 | 45 |
| 47 bool CheckMessageData(const void* bytes, uint32_t num_bytes) { | 46 bool CheckMessageData(const void* bytes, uint32_t num_bytes) { |
| 48 const unsigned char* b = static_cast<const unsigned char*>(bytes); | 47 const unsigned char* b = static_cast<const unsigned char*>(bytes); |
| 49 for (uint32_t i = 0; i < num_bytes; i++) { | 48 for (uint32_t i = 0; i < num_bytes; i++) { |
| 50 if (b[i] != static_cast<unsigned char>(i + num_bytes)) | 49 if (b[i] != static_cast<unsigned char>(i + num_bytes)) |
| 51 return false; | 50 return false; |
| 52 } | 51 } |
| 53 return true; | 52 return true; |
| 54 } | 53 } |
| 55 | 54 |
| 56 void InitOnIOThread(RawChannel* raw_channel) { | 55 void InitOnIOThread(RawChannel* raw_channel, RawChannel::Delegate* delegate) { |
| 57 CHECK(raw_channel->Init()); | 56 CHECK(raw_channel->Init(delegate)); |
| 58 } | 57 } |
| 59 | 58 |
| 60 bool WriteTestMessageToHandle(const embedder::PlatformHandle& handle, | 59 bool WriteTestMessageToHandle(const embedder::PlatformHandle& handle, |
| 61 uint32_t num_bytes) { | 60 uint32_t num_bytes) { |
| 62 scoped_ptr<MessageInTransit> message(MakeTestMessage(num_bytes)); | 61 scoped_ptr<MessageInTransit> message(MakeTestMessage(num_bytes)); |
| 63 | 62 |
| 64 size_t write_size = 0; | 63 size_t write_size = 0; |
| 65 mojo::test::BlockingWrite( | 64 mojo::test::BlockingWrite( |
| 66 handle, message->main_buffer(), message->main_buffer_size(), &write_size); | 65 handle, message->main_buffer(), message->main_buffer_size(), &write_size); |
| 67 return write_size == message->main_buffer_size(); | 66 return write_size == message->main_buffer_size(); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 | 184 |
| 186 // The start of the received data should always be on a message boundary. | 185 // The start of the received data should always be on a message boundary. |
| 187 std::vector<unsigned char> bytes_; | 186 std::vector<unsigned char> bytes_; |
| 188 | 187 |
| 189 DISALLOW_COPY_AND_ASSIGN(TestMessageReaderAndChecker); | 188 DISALLOW_COPY_AND_ASSIGN(TestMessageReaderAndChecker); |
| 190 }; | 189 }; |
| 191 | 190 |
| 192 // Tests writing (and verifies reading using our own custom reader). | 191 // Tests writing (and verifies reading using our own custom reader). |
| 193 TEST_F(RawChannelTest, WriteMessage) { | 192 TEST_F(RawChannelTest, WriteMessage) { |
| 194 WriteOnlyRawChannelDelegate delegate; | 193 WriteOnlyRawChannelDelegate delegate; |
| 195 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), | 194 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); |
| 196 &delegate, | |
| 197 io_thread()->message_loop())); | |
| 198 | |
| 199 TestMessageReaderAndChecker checker(handles[1].get()); | 195 TestMessageReaderAndChecker checker(handles[1].get()); |
| 200 | |
| 201 io_thread()->PostTaskAndWait(FROM_HERE, | 196 io_thread()->PostTaskAndWait(FROM_HERE, |
| 202 base::Bind(&InitOnIOThread, rc.get())); | 197 base::Bind(&InitOnIOThread, rc.get(), |
| 198 base::Unretained(&delegate))); |
| 203 | 199 |
| 204 // Write and read, for a variety of sizes. | 200 // Write and read, for a variety of sizes. |
| 205 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { | 201 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { |
| 206 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); | 202 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); |
| 207 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; | 203 EXPECT_TRUE(checker.ReadAndCheckNextMessage(size)) << size; |
| 208 } | 204 } |
| 209 | 205 |
| 210 // Write/queue and read afterwards, for a variety of sizes. | 206 // Write/queue and read afterwards, for a variety of sizes. |
| 211 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) | 207 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) |
| 212 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); | 208 EXPECT_TRUE(rc->WriteMessage(MakeTestMessage(size))); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 base::Lock lock_; // Protects the following members. | 271 base::Lock lock_; // Protects the following members. |
| 276 std::vector<uint32_t> expected_sizes_; | 272 std::vector<uint32_t> expected_sizes_; |
| 277 size_t position_; | 273 size_t position_; |
| 278 | 274 |
| 279 DISALLOW_COPY_AND_ASSIGN(ReadCheckerRawChannelDelegate); | 275 DISALLOW_COPY_AND_ASSIGN(ReadCheckerRawChannelDelegate); |
| 280 }; | 276 }; |
| 281 | 277 |
| 282 // Tests reading (writing using our own custom writer). | 278 // Tests reading (writing using our own custom writer). |
| 283 TEST_F(RawChannelTest, OnReadMessage) { | 279 TEST_F(RawChannelTest, OnReadMessage) { |
| 284 ReadCheckerRawChannelDelegate delegate; | 280 ReadCheckerRawChannelDelegate delegate; |
| 285 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), | 281 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); |
| 286 &delegate, | |
| 287 io_thread()->message_loop())); | |
| 288 | |
| 289 io_thread()->PostTaskAndWait(FROM_HERE, | 282 io_thread()->PostTaskAndWait(FROM_HERE, |
| 290 base::Bind(&InitOnIOThread, rc.get())); | 283 base::Bind(&InitOnIOThread, rc.get(), |
| 284 base::Unretained(&delegate))); |
| 291 | 285 |
| 292 // Write and read, for a variety of sizes. | 286 // Write and read, for a variety of sizes. |
| 293 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { | 287 for (uint32_t size = 1; size < 5 * 1000 * 1000; size += size / 2 + 1) { |
| 294 delegate.SetExpectedSizes(std::vector<uint32_t>(1, size)); | 288 delegate.SetExpectedSizes(std::vector<uint32_t>(1, size)); |
| 295 | 289 |
| 296 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size)); | 290 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), size)); |
| 297 | 291 |
| 298 delegate.Wait(); | 292 delegate.Wait(); |
| 299 } | 293 } |
| 300 | 294 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 379 size_t count_; | 373 size_t count_; |
| 380 | 374 |
| 381 DISALLOW_COPY_AND_ASSIGN(ReadCountdownRawChannelDelegate); | 375 DISALLOW_COPY_AND_ASSIGN(ReadCountdownRawChannelDelegate); |
| 382 }; | 376 }; |
| 383 | 377 |
| 384 TEST_F(RawChannelTest, WriteMessageAndOnReadMessage) { | 378 TEST_F(RawChannelTest, WriteMessageAndOnReadMessage) { |
| 385 static const size_t kNumWriterThreads = 10; | 379 static const size_t kNumWriterThreads = 10; |
| 386 static const size_t kNumWriteMessagesPerThread = 4000; | 380 static const size_t kNumWriteMessagesPerThread = 4000; |
| 387 | 381 |
| 388 WriteOnlyRawChannelDelegate writer_delegate; | 382 WriteOnlyRawChannelDelegate writer_delegate; |
| 389 scoped_ptr<RawChannel> writer_rc( | 383 scoped_ptr<RawChannel> writer_rc(RawChannel::Create(handles[0].Pass())); |
| 390 RawChannel::Create(handles[0].Pass(), | |
| 391 &writer_delegate, | |
| 392 io_thread()->message_loop())); | |
| 393 | |
| 394 io_thread()->PostTaskAndWait(FROM_HERE, | 384 io_thread()->PostTaskAndWait(FROM_HERE, |
| 395 base::Bind(&InitOnIOThread, writer_rc.get())); | 385 base::Bind(&InitOnIOThread, writer_rc.get(), |
| 386 base::Unretained(&writer_delegate))); |
| 396 | 387 |
| 397 ReadCountdownRawChannelDelegate reader_delegate( | 388 ReadCountdownRawChannelDelegate reader_delegate( |
| 398 kNumWriterThreads * kNumWriteMessagesPerThread); | 389 kNumWriterThreads * kNumWriteMessagesPerThread); |
| 399 scoped_ptr<RawChannel> reader_rc( | 390 scoped_ptr<RawChannel> reader_rc(RawChannel::Create(handles[1].Pass())); |
| 400 RawChannel::Create(handles[1].Pass(), | |
| 401 &reader_delegate, | |
| 402 io_thread()->message_loop())); | |
| 403 | |
| 404 io_thread()->PostTaskAndWait(FROM_HERE, | 391 io_thread()->PostTaskAndWait(FROM_HERE, |
| 405 base::Bind(&InitOnIOThread, reader_rc.get())); | 392 base::Bind(&InitOnIOThread, reader_rc.get(), |
| 393 base::Unretained(&reader_delegate))); |
| 406 | 394 |
| 407 { | 395 { |
| 408 ScopedVector<RawChannelWriterThread> writer_threads; | 396 ScopedVector<RawChannelWriterThread> writer_threads; |
| 409 for (size_t i = 0; i < kNumWriterThreads; i++) { | 397 for (size_t i = 0; i < kNumWriterThreads; i++) { |
| 410 writer_threads.push_back(new RawChannelWriterThread( | 398 writer_threads.push_back(new RawChannelWriterThread( |
| 411 writer_rc.get(), kNumWriteMessagesPerThread)); | 399 writer_rc.get(), kNumWriteMessagesPerThread)); |
| 412 } | 400 } |
| 413 for (size_t i = 0; i < writer_threads.size(); i++) | 401 for (size_t i = 0; i < writer_threads.size(); i++) |
| 414 writer_threads[i]->Start(); | 402 writer_threads[i]->Start(); |
| 415 } // Joins all the writer threads. | 403 } // Joins all the writer threads. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 | 458 |
| 471 bool expecting_read_error_; | 459 bool expecting_read_error_; |
| 472 bool expecting_write_error_; | 460 bool expecting_write_error_; |
| 473 | 461 |
| 474 DISALLOW_COPY_AND_ASSIGN(FatalErrorRecordingRawChannelDelegate); | 462 DISALLOW_COPY_AND_ASSIGN(FatalErrorRecordingRawChannelDelegate); |
| 475 }; | 463 }; |
| 476 | 464 |
| 477 // Tests fatal errors. | 465 // Tests fatal errors. |
| 478 TEST_F(RawChannelTest, OnFatalError) { | 466 TEST_F(RawChannelTest, OnFatalError) { |
| 479 FatalErrorRecordingRawChannelDelegate delegate(0, true, true); | 467 FatalErrorRecordingRawChannelDelegate delegate(0, true, true); |
| 480 | 468 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); |
| 481 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), | |
| 482 &delegate, | |
| 483 io_thread()->message_loop())); | |
| 484 | |
| 485 io_thread()->PostTaskAndWait(FROM_HERE, | 469 io_thread()->PostTaskAndWait(FROM_HERE, |
| 486 base::Bind(&InitOnIOThread, rc.get())); | 470 base::Bind(&InitOnIOThread, rc.get(), |
| 471 base::Unretained(&delegate))); |
| 487 | 472 |
| 488 // Close the handle of the other end, which should make writing fail. | 473 // Close the handle of the other end, which should make writing fail. |
| 489 handles[1].reset(); | 474 handles[1].reset(); |
| 490 | 475 |
| 491 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 476 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 492 | 477 |
| 493 // We should get a write fatal error. | 478 // We should get a write fatal error. |
| 494 delegate.WaitForWriteFatalError(); | 479 delegate.WaitForWriteFatalError(); |
| 495 | 480 |
| 496 // We should also get a read fatal error. | 481 // We should also get a read fatal error. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 518 ++count, message_size += message_size / 2 + 1) { | 503 ++count, message_size += message_size / 2 + 1) { |
| 519 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), message_size)); | 504 EXPECT_TRUE(WriteTestMessageToHandle(handles[1].get(), message_size)); |
| 520 } | 505 } |
| 521 | 506 |
| 522 // Close the other end, which should make writing fail. | 507 // Close the other end, which should make writing fail. |
| 523 handles[1].reset(); | 508 handles[1].reset(); |
| 524 | 509 |
| 525 // Only start up reading here. The system buffer should still contain the | 510 // Only start up reading here. The system buffer should still contain the |
| 526 // messages that were written. | 511 // messages that were written. |
| 527 FatalErrorRecordingRawChannelDelegate delegate(kMessageCount, true, true); | 512 FatalErrorRecordingRawChannelDelegate delegate(kMessageCount, true, true); |
| 528 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), | 513 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); |
| 529 &delegate, | |
| 530 io_thread()->message_loop())); | |
| 531 io_thread()->PostTaskAndWait(FROM_HERE, | 514 io_thread()->PostTaskAndWait(FROM_HERE, |
| 532 base::Bind(&InitOnIOThread, rc.get())); | 515 base::Bind(&InitOnIOThread, rc.get(), |
| 516 base::Unretained(&delegate))); |
| 533 | 517 |
| 534 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 518 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 535 | 519 |
| 536 // We should definitely get a write fatal error. | 520 // We should definitely get a write fatal error. |
| 537 delegate.WaitForWriteFatalError(); | 521 delegate.WaitForWriteFatalError(); |
| 538 | 522 |
| 539 // Wait for reading to finish. A writing failure shouldn't affect reading. | 523 // Wait for reading to finish. A writing failure shouldn't affect reading. |
| 540 delegate.Wait(); | 524 delegate.Wait(); |
| 541 | 525 |
| 542 // And then we should get a read fatal error. | 526 // And then we should get a read fatal error. |
| 543 delegate.WaitForReadFatalError(); | 527 delegate.WaitForReadFatalError(); |
| 544 | 528 |
| 545 io_thread()->PostTaskAndWait(FROM_HERE, | 529 io_thread()->PostTaskAndWait(FROM_HERE, |
| 546 base::Bind(&RawChannel::Shutdown, | 530 base::Bind(&RawChannel::Shutdown, |
| 547 base::Unretained(rc.get()))); | 531 base::Unretained(rc.get()))); |
| 548 } | 532 } |
| 549 | 533 |
| 550 // RawChannelTest.WriteMessageAfterShutdown ------------------------------------ | 534 // RawChannelTest.WriteMessageAfterShutdown ------------------------------------ |
| 551 | 535 |
| 552 // Makes sure that calling |WriteMessage()| after |Shutdown()| behaves | 536 // Makes sure that calling |WriteMessage()| after |Shutdown()| behaves |
| 553 // correctly. | 537 // correctly. |
| 554 TEST_F(RawChannelTest, WriteMessageAfterShutdown) { | 538 TEST_F(RawChannelTest, WriteMessageAfterShutdown) { |
| 555 WriteOnlyRawChannelDelegate delegate; | 539 WriteOnlyRawChannelDelegate delegate; |
| 556 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass(), | 540 scoped_ptr<RawChannel> rc(RawChannel::Create(handles[0].Pass())); |
| 557 &delegate, | |
| 558 io_thread()->message_loop())); | |
| 559 | |
| 560 io_thread()->PostTaskAndWait(FROM_HERE, | 541 io_thread()->PostTaskAndWait(FROM_HERE, |
| 561 base::Bind(&InitOnIOThread, rc.get())); | 542 base::Bind(&InitOnIOThread, rc.get(), |
| 543 base::Unretained(&delegate))); |
| 562 io_thread()->PostTaskAndWait(FROM_HERE, | 544 io_thread()->PostTaskAndWait(FROM_HERE, |
| 563 base::Bind(&RawChannel::Shutdown, | 545 base::Bind(&RawChannel::Shutdown, |
| 564 base::Unretained(rc.get()))); | 546 base::Unretained(rc.get()))); |
| 565 | 547 |
| 566 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); | 548 EXPECT_FALSE(rc->WriteMessage(MakeTestMessage(1))); |
| 567 } | 549 } |
| 568 | 550 |
| 569 } // namespace | 551 } // namespace |
| 570 } // namespace system | 552 } // namespace system |
| 571 } // namespace mojo | 553 } // namespace mojo |
| OLD | NEW |