Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(402)

Side by Side Diff: content/child/shared_memory_data_consumer_handle_unittest.cc

Issue 1144033002: Make SharedMemoryDataConsumerHandle thread-safe. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ipc-data-consumer
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "content/child/shared_memory_data_consumer_handle.h" 5 #include "content/child/shared_memory_data_consumer_handle.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h"
12 #include "base/callback.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/run_loop.h"
15 #include "base/threading/thread.h"
11 #include "testing/gmock/include/gmock/gmock.h" 16 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
13 18
14 namespace content { 19 namespace content {
15 20
16 namespace { 21 namespace {
17 using blink::WebDataConsumerHandle; 22 using blink::WebDataConsumerHandle;
18 using Result = WebDataConsumerHandle::Result; 23 using Result = WebDataConsumerHandle::Result;
19 using Writer = SharedMemoryDataConsumerHandle::Writer; 24 using Writer = SharedMemoryDataConsumerHandle::Writer;
20 using BackpressureMode = SharedMemoryDataConsumerHandle::BackpressureMode; 25 using BackpressureMode = SharedMemoryDataConsumerHandle::BackpressureMode;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 class MockClient : public WebDataConsumerHandle::Client { 101 class MockClient : public WebDataConsumerHandle::Client {
97 public: 102 public:
98 MOCK_METHOD0(didGetReadable, void()); 103 MOCK_METHOD0(didGetReadable, void());
99 }; 104 };
100 105
101 std::string ToString(const void* p, size_t size) { 106 std::string ToString(const void* p, size_t size) {
102 const char* q = static_cast<const char*>(p); 107 const char* q = static_cast<const char*>(p);
103 return std::string(q, q + size); 108 return std::string(q, q + size);
104 } 109 }
105 110
111 class ThreadedSharedMemoryDataConsumerHandleTest : public ::testing::Test {
112 protected:
113 class ReadDataOperation;
114 class ClientImpl final : public WebDataConsumerHandle::Client {
115 public:
116 explicit ClientImpl(ReadDataOperation* operation) : operation_(operation) {}
117
118 void didGetReadable() override { operation_->ReadData(); }
119
120 private:
121 ReadDataOperation* operation_;
122 };
123
124 class ReadDataOperation final {
125 public:
126 typedef WebDataConsumerHandle::Result Result;
127 ReadDataOperation(scoped_ptr<WebDataConsumerHandle> handle,
128 base::MessageLoop* main_message_loop,
129 const base::Closure& on_done)
130 : handle_(handle.Pass()),
131 main_message_loop_(main_message_loop),
132 on_done_(on_done) {}
133
134 const std::string& result() const { return result_; }
135
136 void ReadData() {
137 if (!client_) {
138 client_.reset(new ClientImpl(this));
139 handle_->registerClient(client_.get());
140 }
141
142 Result rv = kOk;
143 size_t readSize = 0;
tyoshino (SeeGerritForStatus) 2015/05/28 11:03:58 chromium style
yhirano 2015/05/28 11:24:41 Done.
144
145 while (true) {
146 char buffer[16];
147 rv = handle_->read(&buffer, sizeof(buffer), kNone, &readSize);
tyoshino (SeeGerritForStatus) 2015/05/28 11:03:58 arraysize?
yhirano 2015/05/28 11:24:41 I think sizeof is correct here, because it is the
148 if (rv != kOk)
149 break;
150 result_.insert(result_.size(), &buffer[0], readSize);
151 }
152
153 if (rv == kShouldWait) {
154 // Wait a while...
155 return;
156 }
157
158 if (rv != kDone) {
159 // Something is wrong.
160 result_ = "error";
161 }
162
163 // The operation is done.
164 main_message_loop_->PostTask(FROM_HERE, on_done_);
165 }
166
167 private:
168 scoped_ptr<WebDataConsumerHandle> handle_;
169 scoped_ptr<WebDataConsumerHandle::Client> client_;
170 base::MessageLoop* main_message_loop_;
171 base::Closure on_done_;
172 std::string result_;
173 };
174
175 void SetUp() override {
176 handle_.reset(
177 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer_));
178 }
179
180 StrictMock<MockClient> client_;
181 scoped_ptr<WebDataConsumerHandle> handle_;
182 scoped_ptr<Writer> writer_;
183 base::MessageLoop loop_;
184 };
185
106 class SharedMemoryDataConsumerHandleTest 186 class SharedMemoryDataConsumerHandleTest
107 : public ::testing::TestWithParam<BackpressureMode> { 187 : public ::testing::TestWithParam<BackpressureMode> {
108 protected: 188 protected:
109 void SetUp() override { 189 void SetUp() override {
110 handle_.reset(new SharedMemoryDataConsumerHandle(GetParam(), &writer_)); 190 handle_.reset(new SharedMemoryDataConsumerHandle(GetParam(), &writer_));
111 } 191 }
112 192
113 StrictMock<MockClient> client_; 193 StrictMock<MockClient> client_;
114 scoped_ptr<SharedMemoryDataConsumerHandle> handle_; 194 scoped_ptr<SharedMemoryDataConsumerHandle> handle_;
115 scoped_ptr<Writer> writer_; 195 scoped_ptr<Writer> writer_;
196 base::MessageLoop loop_;
116 }; 197 };
117 198
118 TEST_P(SharedMemoryDataConsumerHandleTest, ReadFromEmpty) { 199 TEST_P(SharedMemoryDataConsumerHandleTest, ReadFromEmpty) {
119 char buffer[4]; 200 char buffer[4];
120 size_t read = 88; 201 size_t read = 88;
121 Result result = handle_->read(buffer, 4, kNone, &read); 202 Result result = handle_->read(buffer, 4, kNone, &read);
122 203
123 EXPECT_EQ(result, kShouldWait); 204 EXPECT_EQ(result, kShouldWait);
124 EXPECT_EQ(0u, read); 205 EXPECT_EQ(0u, read);
125 } 206 }
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 545
465 writer_->Close(); 546 writer_->Close();
466 547
467 result = handle_->beginRead(&buffer, kNone, &size); 548 result = handle_->beginRead(&buffer, kNone, &size);
468 EXPECT_EQ(kDone, result); 549 EXPECT_EQ(kDone, result);
469 EXPECT_EQ(0u, size); 550 EXPECT_EQ(0u, size);
470 EXPECT_EQ(nullptr, buffer); 551 EXPECT_EQ(nullptr, buffer);
471 } 552 }
472 553
473 TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) { 554 TEST(SharedMemoryDataConsumerHandleBackpressureTest, Read) {
555 base::MessageLoop loop;
474 char buffer[20]; 556 char buffer[20];
475 Result result; 557 Result result;
476 size_t size; 558 size_t size;
477 559
478 scoped_ptr<Writer> writer; 560 scoped_ptr<Writer> writer;
479 auto handle = make_scoped_ptr( 561 auto handle = make_scoped_ptr(
480 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer)); 562 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer));
481 scoped_refptr<Logger> logger(new Logger); 563 scoped_refptr<Logger> logger(new Logger);
482 writer->AddData( 564 writer->AddData(
483 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger))); 565 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
(...skipping 23 matching lines...) Expand all
507 "2\n" 589 "2\n"
508 "data1 is destructed.\n" 590 "data1 is destructed.\n"
509 "3\n" 591 "3\n"
510 "data2 is destructed.\n" 592 "data2 is destructed.\n"
511 "data3 is destructed.\n" 593 "data3 is destructed.\n"
512 "4\n", 594 "4\n",
513 logger->log()); 595 logger->log());
514 } 596 }
515 597
516 TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) { 598 TEST(SharedMemoryDataConsumerHandleBackpressureTest, CloseAndReset) {
599 base::MessageLoop loop;
517 char buffer[20]; 600 char buffer[20];
518 Result result; 601 Result result;
519 size_t size; 602 size_t size;
520 603
521 scoped_ptr<Writer> writer; 604 scoped_ptr<Writer> writer;
522 auto handle = make_scoped_ptr( 605 auto handle = make_scoped_ptr(
523 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer)); 606 new SharedMemoryDataConsumerHandle(kApplyBackpressure, &writer));
524 scoped_refptr<Logger> logger(new Logger); 607 scoped_refptr<Logger> logger(new Logger);
525 writer->AddData( 608 writer->AddData(
526 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger))); 609 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
(...skipping 17 matching lines...) Expand all
544 "2\n" 627 "2\n"
545 "3\n" 628 "3\n"
546 "data1 is destructed.\n" 629 "data1 is destructed.\n"
547 "data2 is destructed.\n" 630 "data2 is destructed.\n"
548 "data3 is destructed.\n" 631 "data3 is destructed.\n"
549 "4\n", 632 "4\n",
550 logger->log()); 633 logger->log());
551 } 634 }
552 635
553 TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest, AddData) { 636 TEST(SharedMemoryDataConsumerHandleWithoutBackpressureTest, AddData) {
637 base::MessageLoop loop;
554 scoped_ptr<Writer> writer; 638 scoped_ptr<Writer> writer;
555 auto handle = make_scoped_ptr( 639 auto handle = make_scoped_ptr(
556 new SharedMemoryDataConsumerHandle(kDoNotApplyBackpressure, &writer)); 640 new SharedMemoryDataConsumerHandle(kDoNotApplyBackpressure, &writer));
557 scoped_refptr<Logger> logger(new Logger); 641 scoped_refptr<Logger> logger(new Logger);
558 642
559 logger->Add("1"); 643 logger->Add("1");
560 writer->AddData( 644 writer->AddData(
561 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger))); 645 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
562 logger->Add("2"); 646 logger->Add("2");
563 writer->AddData( 647 writer->AddData(
564 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger))); 648 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
565 logger->Add("3"); 649 logger->Add("3");
566 650
567 EXPECT_EQ( 651 EXPECT_EQ(
568 "1\n" 652 "1\n"
569 "data1 is destructed.\n" 653 "data1 is destructed.\n"
570 "2\n" 654 "2\n"
571 "data2 is destructed.\n" 655 "data2 is destructed.\n"
572 "3\n", 656 "3\n",
573 logger->log()); 657 logger->log());
574 } 658 }
575 659
660 TEST_F(ThreadedSharedMemoryDataConsumerHandleTest, Read) {
661 base::RunLoop run_loop;
662 auto operation = make_scoped_ptr(
663 new ReadDataOperation(handle_.Pass(), &loop_, run_loop.QuitClosure()));
664 scoped_refptr<Logger> logger(new Logger);
665
666 base::Thread t("DataConsumerHandle test thread");
667 ASSERT_TRUE(t.Start());
668
669 t.message_loop()->PostTask(FROM_HERE,
670 base::Bind(&ReadDataOperation::ReadData,
671 base::Unretained(operation.get())));
672
673 logger->Add("1");
674 writer_->AddData(
675 make_scoped_ptr(new LoggingFixedReceivedData("data1", "Once ", logger)));
676 writer_->AddData(
677 make_scoped_ptr(new LoggingFixedReceivedData("data2", "upon ", logger)));
678 writer_->AddData(make_scoped_ptr(
679 new LoggingFixedReceivedData("data3", "a time ", logger)));
680 writer_->AddData(
681 make_scoped_ptr(new LoggingFixedReceivedData("data4", "there ", logger)));
682 writer_->AddData(
683 make_scoped_ptr(new LoggingFixedReceivedData("data5", "was ", logger)));
684 writer_->Close();
685 logger->Add("2");
686
687 run_loop.Run();
688 t.Stop();
689
690 EXPECT_EQ("Once upon a time there was ", operation->result());
691 EXPECT_EQ(
692 "1\n"
693 "2\n"
694 "data1 is destructed.\n"
695 "data2 is destructed.\n"
696 "data3 is destructed.\n"
697 "data4 is destructed.\n"
698 "data5 is destructed.\n",
699 logger->log());
700 }
701
576 INSTANTIATE_TEST_CASE_P(SharedMemoryDataConsumerHandleTest, 702 INSTANTIATE_TEST_CASE_P(SharedMemoryDataConsumerHandleTest,
577 SharedMemoryDataConsumerHandleTest, 703 SharedMemoryDataConsumerHandleTest,
578 ::testing::Values(kApplyBackpressure, 704 ::testing::Values(kApplyBackpressure,
579 kDoNotApplyBackpressure)); 705 kDoNotApplyBackpressure));
580 } // namespace 706 } // namespace
581 707
582 } // namespace content 708 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698