[MediaRouter] Update MR-2-Extension's PostMessage to return boolean.
[chromium-blink-merge.git] / chromecast / media / cma / ipc / media_message_fifo_unittest.cc
blob6680451374b0d67df470bfbed58e9555de283ca4
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
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/bind.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/synchronization/waitable_event.h"
9 #include "base/threading/thread.h"
10 #include "chromecast/media/cma/ipc/media_memory_chunk.h"
11 #include "chromecast/media/cma/ipc/media_message.h"
12 #include "chromecast/media/cma/ipc/media_message_fifo.h"
13 #include "chromecast/media/cma/ipc/media_message_type.h"
14 #include "testing/gtest/include/gtest/gtest.h"
16 namespace chromecast {
17 namespace media {
19 namespace {
21 class FifoMemoryChunk : public MediaMemoryChunk {
22 public:
23 FifoMemoryChunk(void* mem, size_t size)
24 : mem_(mem), size_(size) {}
25 ~FifoMemoryChunk() override {}
27 void* data() const override { return mem_; }
28 size_t size() const override { return size_; }
29 bool valid() const override { return true; }
31 private:
32 void* mem_;
33 size_t size_;
35 DISALLOW_COPY_AND_ASSIGN(FifoMemoryChunk);
38 void MsgProducer(scoped_ptr<MediaMessageFifo> fifo,
39 int msg_count,
40 base::WaitableEvent* event) {
42 for (int k = 0; k < msg_count; k++) {
43 uint32 msg_type = 0x2 + (k % 5);
44 uint32 max_msg_content_size = k % 64;
45 do {
46 scoped_ptr<MediaMessage> msg1(
47 MediaMessage::CreateMessage(
48 msg_type,
49 base::Bind(&MediaMessageFifo::ReserveMemory,
50 base::Unretained(fifo.get())),
51 max_msg_content_size));
52 if (msg1)
53 break;
54 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
55 } while(true);
58 fifo.reset();
60 event->Signal();
63 void MsgConsumer(scoped_ptr<MediaMessageFifo> fifo,
64 int msg_count,
65 base::WaitableEvent* event) {
67 int k = 0;
68 while (k < msg_count) {
69 uint32 msg_type = 0x2 + (k % 5);
70 do {
71 scoped_ptr<MediaMessage> msg2(fifo->Pop());
72 if (msg2) {
73 if (msg2->type() != PaddingMediaMsg) {
74 EXPECT_EQ(msg2->type(), msg_type);
75 k++;
77 break;
79 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
80 } while(true);
83 fifo.reset();
85 event->Signal();
88 void MsgProducerConsumer(
89 scoped_ptr<MediaMessageFifo> producer_fifo,
90 scoped_ptr<MediaMessageFifo> consumer_fifo,
91 base::WaitableEvent* event) {
92 for (int k = 0; k < 2048; k++) {
93 // Should have enough space to create a message.
94 uint32 msg_type = 0x2 + (k % 5);
95 uint32 max_msg_content_size = k % 64;
96 scoped_ptr<MediaMessage> msg1(
97 MediaMessage::CreateMessage(
98 msg_type,
99 base::Bind(&MediaMessageFifo::ReserveMemory,
100 base::Unretained(producer_fifo.get())),
101 max_msg_content_size));
102 EXPECT_TRUE(msg1);
104 // Make sure the message is commited.
105 msg1.reset();
107 // At this point, we should have a message to read.
108 scoped_ptr<MediaMessage> msg2(consumer_fifo->Pop());
109 EXPECT_TRUE(msg2);
112 producer_fifo.reset();
113 consumer_fifo.reset();
115 event->Signal();
118 } // namespace
120 TEST(MediaMessageFifoTest, AlternateWriteRead) {
121 size_t buffer_size = 64 * 1024;
122 scoped_ptr<uint64[]> buffer(new uint64[buffer_size / sizeof(uint64)]);
124 scoped_ptr<base::Thread> thread(
125 new base::Thread("FeederConsumerThread"));
126 thread->Start();
128 scoped_ptr<MediaMessageFifo> producer_fifo(new MediaMessageFifo(
129 scoped_ptr<MediaMemoryChunk>(
130 new FifoMemoryChunk(&buffer[0], buffer_size)),
131 true));
132 scoped_ptr<MediaMessageFifo> consumer_fifo(new MediaMessageFifo(
133 scoped_ptr<MediaMemoryChunk>(
134 new FifoMemoryChunk(&buffer[0], buffer_size)),
135 false));
137 base::WaitableEvent event(false, false);
138 thread->task_runner()->PostTask(
139 FROM_HERE, base::Bind(&MsgProducerConsumer, base::Passed(&producer_fifo),
140 base::Passed(&consumer_fifo), &event));
141 event.Wait();
143 thread.reset();
146 TEST(MediaMessageFifoTest, MultiThreaded) {
147 size_t buffer_size = 64 * 1024;
148 scoped_ptr<uint64[]> buffer(new uint64[buffer_size / sizeof(uint64)]);
150 scoped_ptr<base::Thread> producer_thread(
151 new base::Thread("FeederThread"));
152 scoped_ptr<base::Thread> consumer_thread(
153 new base::Thread("ConsumerThread"));
154 producer_thread->Start();
155 consumer_thread->Start();
157 scoped_ptr<MediaMessageFifo> producer_fifo(new MediaMessageFifo(
158 scoped_ptr<MediaMemoryChunk>(
159 new FifoMemoryChunk(&buffer[0], buffer_size)),
160 true));
161 scoped_ptr<MediaMessageFifo> consumer_fifo(new MediaMessageFifo(
162 scoped_ptr<MediaMemoryChunk>(
163 new FifoMemoryChunk(&buffer[0], buffer_size)),
164 false));
166 base::WaitableEvent producer_event_done(false, false);
167 base::WaitableEvent consumer_event_done(false, false);
169 const int msg_count = 2048;
170 producer_thread->task_runner()->PostTask(
171 FROM_HERE, base::Bind(&MsgProducer, base::Passed(&producer_fifo),
172 msg_count, &producer_event_done));
173 consumer_thread->task_runner()->PostTask(
174 FROM_HERE, base::Bind(&MsgConsumer, base::Passed(&consumer_fifo),
175 msg_count, &consumer_event_done));
177 producer_event_done.Wait();
178 consumer_event_done.Wait();
180 producer_thread.reset();
181 consumer_thread.reset();
184 } // namespace media
185 } // namespace chromecast