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
3 // found in the LICENSE file.
4
5 #include "mojo/system/message_pipe.h"
6
7 #include "base/memory/ref_counted.h"
8 #include "base/threading/platform_thread.h" // For |Sleep()|.
9 #include "base/time/time.h"
10 #include "mojo/system/waiter.h"
11 #include "mojo/system/waiter_test_utils.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace mojo {
15 namespace system {
16 namespace {
17
18 // Tests:
19 // - only default flags
20 // - reading messages from a port
21 // - when there are no/one/two messages available for that port
22 // - with buffer size 0 (and null 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
25 // - writing messages to a port
26 // - in the obvious scenarios (as above)
27 // - to a port that's been closed
28 // - writing a message to a port, closing the other (would be the source) port,
29 // and reading it
TEST(MessagePipeTest,Basic)30 TEST(MessagePipeTest, Basic) {
31 scoped_refptr<MessagePipe> mp(new MessagePipe());
32
33 int32_t buffer[2];
34 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
35 uint32_t buffer_size;
36
37 // Nothing to read yet on port 0.
38 buffer[0] = 123;
39 buffer[1] = 456;
40 buffer_size = kBufferSize;
41 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
42 mp->ReadMessage(0,
43 buffer, &buffer_size,
44 0, NULL,
45 MOJO_READ_MESSAGE_FLAG_NONE));
46 EXPECT_EQ(kBufferSize, buffer_size);
47 EXPECT_EQ(123, buffer[0]);
48 EXPECT_EQ(456, buffer[1]);
49
50 // Ditto for port 1.
51 buffer[0] = 123;
52 buffer[1] = 456;
53 buffer_size = kBufferSize;
54 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
55 mp->ReadMessage(1,
56 buffer, &buffer_size,
57 0, NULL,
58 MOJO_READ_MESSAGE_FLAG_NONE));
59
60 // Write from port 1 (to port 0).
61 buffer[0] = 789012345;
62 buffer[1] = 0;
63 EXPECT_EQ(MOJO_RESULT_OK,
64 mp->WriteMessage(1,
65 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
66 NULL,
67 MOJO_WRITE_MESSAGE_FLAG_NONE));
68
69 // Read from port 0.
70 buffer[0] = 123;
71 buffer[1] = 456;
72 buffer_size = kBufferSize;
73 EXPECT_EQ(MOJO_RESULT_OK,
74 mp->ReadMessage(0,
75 buffer, &buffer_size,
76 0, NULL,
77 MOJO_READ_MESSAGE_FLAG_NONE));
78 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
79 EXPECT_EQ(789012345, buffer[0]);
80 EXPECT_EQ(456, buffer[1]);
81
82 // Read again from port 0 -- it should be empty.
83 buffer_size = kBufferSize;
84 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
85 mp->ReadMessage(0,
86 buffer, &buffer_size,
87 0, NULL,
88 MOJO_READ_MESSAGE_FLAG_NONE));
89
90 // Write two messages from port 0 (to port 1).
91 buffer[0] = 123456789;
92 buffer[1] = 0;
93 EXPECT_EQ(MOJO_RESULT_OK,
94 mp->WriteMessage(0,
95 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
96 NULL,
97 MOJO_WRITE_MESSAGE_FLAG_NONE));
98 buffer[0] = 234567890;
99 buffer[1] = 0;
100 EXPECT_EQ(MOJO_RESULT_OK,
101 mp->WriteMessage(0,
102 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
103 NULL,
104 MOJO_WRITE_MESSAGE_FLAG_NONE));
105
106 // Read from port 1 with buffer size 0 (should get the size of next message).
107 // Also test that giving a null buffer is okay when the buffer size is 0.
108 buffer_size = 0;
109 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
110 mp->ReadMessage(1,
111 NULL, &buffer_size,
112 0, NULL,
113 MOJO_READ_MESSAGE_FLAG_NONE));
114 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
115
116 // Read from port 1 with buffer size 1 (too small; should get the size of next
117 // message).
118 buffer[0] = 123;
119 buffer[1] = 456;
120 buffer_size = 1;
121 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
122 mp->ReadMessage(1,
123 buffer, &buffer_size,
124 0, NULL,
125 MOJO_READ_MESSAGE_FLAG_NONE));
126 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
127 EXPECT_EQ(123, buffer[0]);
128 EXPECT_EQ(456, buffer[1]);
129
130 // Read from port 1.
131 buffer[0] = 123;
132 buffer[1] = 456;
133 buffer_size = kBufferSize;
134 EXPECT_EQ(MOJO_RESULT_OK,
135 mp->ReadMessage(1,
136 buffer, &buffer_size,
137 0, NULL,
138 MOJO_READ_MESSAGE_FLAG_NONE));
139 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
140 EXPECT_EQ(123456789, buffer[0]);
141 EXPECT_EQ(456, buffer[1]);
142
143 // Read again from port 1.
144 buffer[0] = 123;
145 buffer[1] = 456;
146 buffer_size = kBufferSize;
147 EXPECT_EQ(MOJO_RESULT_OK,
148 mp->ReadMessage(1,
149 buffer, &buffer_size,
150 0, NULL,
151 MOJO_READ_MESSAGE_FLAG_NONE));
152 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
153 EXPECT_EQ(234567890, buffer[0]);
154 EXPECT_EQ(456, buffer[1]);
155
156 // Read again from port 1 -- it should be empty.
157 buffer_size = kBufferSize;
158 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
159 mp->ReadMessage(1,
160 buffer, &buffer_size,
161 0, NULL,
162 MOJO_READ_MESSAGE_FLAG_NONE));
163
164 // Write from port 0 (to port 1).
165 buffer[0] = 345678901;
166 buffer[1] = 0;
167 EXPECT_EQ(MOJO_RESULT_OK,
168 mp->WriteMessage(0,
169 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
170 NULL,
171 MOJO_WRITE_MESSAGE_FLAG_NONE));
172
173 // Close port 0.
174 mp->Close(0);
175
176 // Try to write from port 1 (to port 0).
177 buffer[0] = 456789012;
178 buffer[1] = 0;
179 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
180 mp->WriteMessage(1,
181 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
182 NULL,
183 MOJO_WRITE_MESSAGE_FLAG_NONE));
184
185 // Read from port 1; should still get message (even though port 0 was closed).
186 buffer[0] = 123;
187 buffer[1] = 456;
188 buffer_size = kBufferSize;
189 EXPECT_EQ(MOJO_RESULT_OK,
190 mp->ReadMessage(1,
191 buffer, &buffer_size,
192 0, NULL,
193 MOJO_READ_MESSAGE_FLAG_NONE));
194 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
195 EXPECT_EQ(345678901, buffer[0]);
196 EXPECT_EQ(456, buffer[1]);
197
198 // Read again from port 1 -- it should be empty (and port 0 is closed).
199 buffer_size = kBufferSize;
200 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
201 mp->ReadMessage(1,
202 buffer, &buffer_size,
203 0, NULL,
204 MOJO_READ_MESSAGE_FLAG_NONE));
205
206 mp->Close(1);
207 }
208
TEST(MessagePipeTest,CloseWithQueuedIncomingMessages)209 TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) {
210 scoped_refptr<MessagePipe> mp(new MessagePipe());
211
212 int32_t buffer[1];
213 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
214 uint32_t buffer_size;
215
216 // Write some messages from port 1 (to port 0).
217 for (int32_t i = 0; i < 5; i++) {
218 buffer[0] = i;
219 EXPECT_EQ(MOJO_RESULT_OK,
220 mp->WriteMessage(1,
221 buffer, kBufferSize,
222 NULL,
223 MOJO_WRITE_MESSAGE_FLAG_NONE));
224 }
225
226 // Port 0 shouldn't be empty.
227 buffer_size = 0;
228 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
229 mp->ReadMessage(0,
230 NULL, &buffer_size,
231 0, NULL,
232 MOJO_READ_MESSAGE_FLAG_NONE));
233 EXPECT_EQ(kBufferSize, buffer_size);
234
235 // Close port 0 first, which should have outstanding (incoming) messages.
236 mp->Close(0);
237 mp->Close(1);
238 }
239
TEST(MessagePipeTest,DiscardMode)240 TEST(MessagePipeTest, DiscardMode) {
241 scoped_refptr<MessagePipe> mp(new MessagePipe());
242
243 int32_t buffer[2];
244 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
245 uint32_t buffer_size;
246
247 // Write from port 1 (to port 0).
248 buffer[0] = 789012345;
249 buffer[1] = 0;
250 EXPECT_EQ(MOJO_RESULT_OK,
251 mp->WriteMessage(1,
252 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
253 NULL,
254 MOJO_WRITE_MESSAGE_FLAG_NONE));
255
256 // Read/discard from port 0 (no buffer); get size.
257 buffer_size = 0;
258 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
259 mp->ReadMessage(0,
260 NULL, &buffer_size,
261 0, NULL,
262 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
263 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
264
265 // Read again from port 0 -- it should be empty.
266 buffer_size = kBufferSize;
267 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
268 mp->ReadMessage(0,
269 buffer, &buffer_size,
270 0, NULL,
271 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
272
273 // Write from port 1 (to port 0).
274 buffer[0] = 890123456;
275 buffer[1] = 0;
276 EXPECT_EQ(MOJO_RESULT_OK,
277 mp->WriteMessage(1,
278 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
279 NULL,
280 MOJO_WRITE_MESSAGE_FLAG_NONE));
281
282 // Read from port 0 (buffer big enough).
283 buffer[0] = 123;
284 buffer[1] = 456;
285 buffer_size = kBufferSize;
286 EXPECT_EQ(MOJO_RESULT_OK,
287 mp->ReadMessage(0,
288 buffer, &buffer_size,
289 0, NULL,
290 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
291 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
292 EXPECT_EQ(890123456, buffer[0]);
293 EXPECT_EQ(456, buffer[1]);
294
295 // Read again from port 0 -- it should be empty.
296 buffer_size = kBufferSize;
297 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
298 mp->ReadMessage(0,
299 buffer, &buffer_size,
300 0, NULL,
301 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
302
303 // Write from port 1 (to port 0).
304 buffer[0] = 901234567;
305 buffer[1] = 0;
306 EXPECT_EQ(MOJO_RESULT_OK,
307 mp->WriteMessage(1,
308 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
309 NULL,
310 MOJO_WRITE_MESSAGE_FLAG_NONE));
311
312 // Read/discard from port 0 (buffer too small); get size.
313 buffer_size = 1;
314 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
315 mp->ReadMessage(0,
316 buffer, &buffer_size,
317 0, NULL,
318 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
319 EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
320
321 // Read again from port 0 -- it should be empty.
322 buffer_size = kBufferSize;
323 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
324 mp->ReadMessage(0,
325 buffer, &buffer_size,
326 0, NULL,
327 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
328
329 // Write from port 1 (to port 0).
330 buffer[0] = 123456789;
331 buffer[1] = 0;
332 EXPECT_EQ(MOJO_RESULT_OK,
333 mp->WriteMessage(1,
334 buffer, static_cast<uint32_t>(sizeof(buffer[0])),
335 NULL,
336 MOJO_WRITE_MESSAGE_FLAG_NONE));
337
338 // Discard from port 0.
339 buffer_size = 1;
340 EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
341 mp->ReadMessage(0,
342 NULL, NULL,
343 0, NULL,
344 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
345
346 // Read again from port 0 -- it should be empty.
347 buffer_size = kBufferSize;
348 EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
349 mp->ReadMessage(0,
350 buffer, &buffer_size,
351 0, NULL,
352 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
353
354 mp->Close(0);
355 mp->Close(1);
356 }
357
TEST(MessagePipeTest,BasicWaiting)358 TEST(MessagePipeTest, BasicWaiting) {
359 scoped_refptr<MessagePipe> mp(new MessagePipe());
360 Waiter waiter;
361
362 int32_t buffer[1];
363 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
364 uint32_t buffer_size;
365
366 // Always writable (until the other port is closed).
367 waiter.Init();
368 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
369 mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0));
370 waiter.Init();
371 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
372 mp->AddWaiter(0,
373 &waiter,
374 MOJO_HANDLE_SIGNAL_READABLE |
375 MOJO_HANDLE_SIGNAL_WRITABLE,
376 0));
377
378 // Not yet readable.
379 waiter.Init();
380 EXPECT_EQ(MOJO_RESULT_OK,
381 mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 1));
382 EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, NULL));
383 mp->RemoveWaiter(0, &waiter);
384
385 // Write from port 0 (to port 1), to make port 1 readable.
386 buffer[0] = 123456789;
387 EXPECT_EQ(MOJO_RESULT_OK,
388 mp->WriteMessage(0,
389 buffer, kBufferSize,
390 NULL,
391 MOJO_WRITE_MESSAGE_FLAG_NONE));
392
393 // Port 1 should already be readable now.
394 waiter.Init();
395 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
396 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 2));
397 waiter.Init();
398 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
399 mp->AddWaiter(1,
400 &waiter,
401 MOJO_HANDLE_SIGNAL_READABLE |
402 MOJO_HANDLE_SIGNAL_WRITABLE,
403 0));
404 // ... and still writable.
405 waiter.Init();
406 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
407 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 3));
408
409 // Close port 0.
410 mp->Close(0);
411
412 // Now port 1 should not be writable.
413 waiter.Init();
414 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
415 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 4));
416
417 // But it should still be readable.
418 waiter.Init();
419 EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
420 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 5));
421
422 // Read from port 1.
423 buffer[0] = 0;
424 buffer_size = kBufferSize;
425 EXPECT_EQ(MOJO_RESULT_OK,
426 mp->ReadMessage(1,
427 buffer, &buffer_size,
428 0, NULL,
429 MOJO_READ_MESSAGE_FLAG_NONE));
430 EXPECT_EQ(123456789, buffer[0]);
431
432 // Now port 1 should no longer be readable.
433 waiter.Init();
434 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
435 mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 6));
436
437 mp->Close(1);
438 }
439
TEST(MessagePipeTest,ThreadedWaiting)440 TEST(MessagePipeTest, ThreadedWaiting) {
441 int32_t buffer[1];
442 const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
443
444 MojoResult result;
445 uint32_t context;
446
447 // Write to wake up waiter waiting for read.
448 {
449 scoped_refptr<MessagePipe> mp(new MessagePipe());
450 test::SimpleWaiterThread thread(&result, &context);
451
452 thread.waiter()->Init();
453 EXPECT_EQ(MOJO_RESULT_OK,
454 mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE,
455 1));
456 thread.Start();
457
458 buffer[0] = 123456789;
459 // Write from port 0 (to port 1), which should wake up the waiter.
460 EXPECT_EQ(MOJO_RESULT_OK,
461 mp->WriteMessage(0,
462 buffer, kBufferSize,
463 NULL,
464 MOJO_WRITE_MESSAGE_FLAG_NONE));
465
466 mp->RemoveWaiter(1, thread.waiter());
467
468 mp->Close(0);
469 mp->Close(1);
470 } // Joins |thread|.
471 // The waiter should have woken up successfully.
472 EXPECT_EQ(MOJO_RESULT_OK, result);
473 EXPECT_EQ(1u, context);
474
475 // Close to cancel waiter.
476 {
477 scoped_refptr<MessagePipe> mp(new MessagePipe());
478 test::SimpleWaiterThread thread(&result, &context);
479
480 thread.waiter()->Init();
481 EXPECT_EQ(MOJO_RESULT_OK,
482 mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE,
483 2));
484 thread.Start();
485
486 // Close port 1 first -- this should result in the waiter being cancelled.
487 mp->CancelAllWaiters(1);
488 mp->Close(1);
489
490 // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the
491 // |MessagePipe| to remove any waiter.
492
493 mp->Close(0);
494 } // Joins |thread|.
495 EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
496 EXPECT_EQ(2u, context);
497
498 // Close to make waiter un-wake-up-able.
499 {
500 scoped_refptr<MessagePipe> mp(new MessagePipe());
501 test::SimpleWaiterThread thread(&result, &context);
502
503 thread.waiter()->Init();
504 EXPECT_EQ(MOJO_RESULT_OK,
505 mp->AddWaiter(1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE,
506 3));
507 thread.Start();
508
509 // Close port 0 first -- this should wake the waiter up, since port 1 will
510 // never be readable.
511 mp->CancelAllWaiters(0);
512 mp->Close(0);
513
514 mp->RemoveWaiter(1, thread.waiter());
515
516 mp->CancelAllWaiters(1);
517 mp->Close(1);
518 } // Joins |thread|.
519 EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
520 EXPECT_EQ(3u, context);
521 }
522
523 } // namespace
524 } // namespace system
525 } // namespace mojo
526