• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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