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
14namespace mojo {
15namespace system {
16namespace {
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
30TEST(MessagePipeTest, Basic) {
31  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
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                            UserPointer<void>(buffer),
44                            MakeUserPointer(&buffer_size),
45                            0,
46                            nullptr,
47                            MOJO_READ_MESSAGE_FLAG_NONE));
48  EXPECT_EQ(kBufferSize, buffer_size);
49  EXPECT_EQ(123, buffer[0]);
50  EXPECT_EQ(456, buffer[1]);
51
52  // Ditto for port 1.
53  buffer[0] = 123;
54  buffer[1] = 456;
55  buffer_size = kBufferSize;
56  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
57            mp->ReadMessage(1,
58                            UserPointer<void>(buffer),
59                            MakeUserPointer(&buffer_size),
60                            0,
61                            nullptr,
62                            MOJO_READ_MESSAGE_FLAG_NONE));
63
64  // Write from port 1 (to port 0).
65  buffer[0] = 789012345;
66  buffer[1] = 0;
67  EXPECT_EQ(MOJO_RESULT_OK,
68            mp->WriteMessage(1,
69                             UserPointer<const void>(buffer),
70                             static_cast<uint32_t>(sizeof(buffer[0])),
71                             nullptr,
72                             MOJO_WRITE_MESSAGE_FLAG_NONE));
73
74  // Read from port 0.
75  buffer[0] = 123;
76  buffer[1] = 456;
77  buffer_size = kBufferSize;
78  EXPECT_EQ(MOJO_RESULT_OK,
79            mp->ReadMessage(0,
80                            UserPointer<void>(buffer),
81                            MakeUserPointer(&buffer_size),
82                            0,
83                            nullptr,
84                            MOJO_READ_MESSAGE_FLAG_NONE));
85  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
86  EXPECT_EQ(789012345, buffer[0]);
87  EXPECT_EQ(456, buffer[1]);
88
89  // Read again from port 0 -- it should be empty.
90  buffer_size = kBufferSize;
91  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
92            mp->ReadMessage(0,
93                            UserPointer<void>(buffer),
94                            MakeUserPointer(&buffer_size),
95                            0,
96                            nullptr,
97                            MOJO_READ_MESSAGE_FLAG_NONE));
98
99  // Write two messages from port 0 (to port 1).
100  buffer[0] = 123456789;
101  buffer[1] = 0;
102  EXPECT_EQ(MOJO_RESULT_OK,
103            mp->WriteMessage(0,
104                             UserPointer<const void>(buffer),
105                             static_cast<uint32_t>(sizeof(buffer[0])),
106                             nullptr,
107                             MOJO_WRITE_MESSAGE_FLAG_NONE));
108  buffer[0] = 234567890;
109  buffer[1] = 0;
110  EXPECT_EQ(MOJO_RESULT_OK,
111            mp->WriteMessage(0,
112                             UserPointer<const void>(buffer),
113                             static_cast<uint32_t>(sizeof(buffer[0])),
114                             nullptr,
115                             MOJO_WRITE_MESSAGE_FLAG_NONE));
116
117  // Read from port 1 with buffer size 0 (should get the size of next message).
118  // Also test that giving a null buffer is okay when the buffer size is 0.
119  buffer_size = 0;
120  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
121            mp->ReadMessage(1,
122                            NullUserPointer(),
123                            MakeUserPointer(&buffer_size),
124                            0,
125                            nullptr,
126                            MOJO_READ_MESSAGE_FLAG_NONE));
127  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
128
129  // Read from port 1 with buffer size 1 (too small; should get the size of next
130  // message).
131  buffer[0] = 123;
132  buffer[1] = 456;
133  buffer_size = 1;
134  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
135            mp->ReadMessage(1,
136                            UserPointer<void>(buffer),
137                            MakeUserPointer(&buffer_size),
138                            0,
139                            nullptr,
140                            MOJO_READ_MESSAGE_FLAG_NONE));
141  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
142  EXPECT_EQ(123, buffer[0]);
143  EXPECT_EQ(456, buffer[1]);
144
145  // Read from port 1.
146  buffer[0] = 123;
147  buffer[1] = 456;
148  buffer_size = kBufferSize;
149  EXPECT_EQ(MOJO_RESULT_OK,
150            mp->ReadMessage(1,
151                            UserPointer<void>(buffer),
152                            MakeUserPointer(&buffer_size),
153                            0,
154                            nullptr,
155                            MOJO_READ_MESSAGE_FLAG_NONE));
156  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
157  EXPECT_EQ(123456789, buffer[0]);
158  EXPECT_EQ(456, buffer[1]);
159
160  // Read again from port 1.
161  buffer[0] = 123;
162  buffer[1] = 456;
163  buffer_size = kBufferSize;
164  EXPECT_EQ(MOJO_RESULT_OK,
165            mp->ReadMessage(1,
166                            UserPointer<void>(buffer),
167                            MakeUserPointer(&buffer_size),
168                            0,
169                            nullptr,
170                            MOJO_READ_MESSAGE_FLAG_NONE));
171  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
172  EXPECT_EQ(234567890, buffer[0]);
173  EXPECT_EQ(456, buffer[1]);
174
175  // Read again from port 1 -- it should be empty.
176  buffer_size = kBufferSize;
177  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
178            mp->ReadMessage(1,
179                            UserPointer<void>(buffer),
180                            MakeUserPointer(&buffer_size),
181                            0,
182                            nullptr,
183                            MOJO_READ_MESSAGE_FLAG_NONE));
184
185  // Write from port 0 (to port 1).
186  buffer[0] = 345678901;
187  buffer[1] = 0;
188  EXPECT_EQ(MOJO_RESULT_OK,
189            mp->WriteMessage(0,
190                             UserPointer<const void>(buffer),
191                             static_cast<uint32_t>(sizeof(buffer[0])),
192                             nullptr,
193                             MOJO_WRITE_MESSAGE_FLAG_NONE));
194
195  // Close port 0.
196  mp->Close(0);
197
198  // Try to write from port 1 (to port 0).
199  buffer[0] = 456789012;
200  buffer[1] = 0;
201  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
202            mp->WriteMessage(1,
203                             UserPointer<const void>(buffer),
204                             static_cast<uint32_t>(sizeof(buffer[0])),
205                             nullptr,
206                             MOJO_WRITE_MESSAGE_FLAG_NONE));
207
208  // Read from port 1; should still get message (even though port 0 was closed).
209  buffer[0] = 123;
210  buffer[1] = 456;
211  buffer_size = kBufferSize;
212  EXPECT_EQ(MOJO_RESULT_OK,
213            mp->ReadMessage(1,
214                            UserPointer<void>(buffer),
215                            MakeUserPointer(&buffer_size),
216                            0,
217                            nullptr,
218                            MOJO_READ_MESSAGE_FLAG_NONE));
219  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
220  EXPECT_EQ(345678901, buffer[0]);
221  EXPECT_EQ(456, buffer[1]);
222
223  // Read again from port 1 -- it should be empty (and port 0 is closed).
224  buffer_size = kBufferSize;
225  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
226            mp->ReadMessage(1,
227                            UserPointer<void>(buffer),
228                            MakeUserPointer(&buffer_size),
229                            0,
230                            nullptr,
231                            MOJO_READ_MESSAGE_FLAG_NONE));
232
233  mp->Close(1);
234}
235
236TEST(MessagePipeTest, CloseWithQueuedIncomingMessages) {
237  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
238
239  int32_t buffer[1];
240  const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
241  uint32_t buffer_size;
242
243  // Write some messages from port 1 (to port 0).
244  for (int32_t i = 0; i < 5; i++) {
245    buffer[0] = i;
246    EXPECT_EQ(MOJO_RESULT_OK,
247              mp->WriteMessage(1,
248                               UserPointer<const void>(buffer),
249                               kBufferSize,
250                               nullptr,
251                               MOJO_WRITE_MESSAGE_FLAG_NONE));
252  }
253
254  // Port 0 shouldn't be empty.
255  buffer_size = 0;
256  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
257            mp->ReadMessage(0,
258                            NullUserPointer(),
259                            MakeUserPointer(&buffer_size),
260                            0,
261                            nullptr,
262                            MOJO_READ_MESSAGE_FLAG_NONE));
263  EXPECT_EQ(kBufferSize, buffer_size);
264
265  // Close port 0 first, which should have outstanding (incoming) messages.
266  mp->Close(0);
267  mp->Close(1);
268}
269
270TEST(MessagePipeTest, DiscardMode) {
271  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
272
273  int32_t buffer[2];
274  const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
275  uint32_t buffer_size;
276
277  // Write from port 1 (to port 0).
278  buffer[0] = 789012345;
279  buffer[1] = 0;
280  EXPECT_EQ(MOJO_RESULT_OK,
281            mp->WriteMessage(1,
282                             UserPointer<const void>(buffer),
283                             static_cast<uint32_t>(sizeof(buffer[0])),
284                             nullptr,
285                             MOJO_WRITE_MESSAGE_FLAG_NONE));
286
287  // Read/discard from port 0 (no buffer); get size.
288  buffer_size = 0;
289  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
290            mp->ReadMessage(0,
291                            NullUserPointer(),
292                            MakeUserPointer(&buffer_size),
293                            0,
294                            nullptr,
295                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
296  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
297
298  // Read again from port 0 -- it should be empty.
299  buffer_size = kBufferSize;
300  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
301            mp->ReadMessage(0,
302                            UserPointer<void>(buffer),
303                            MakeUserPointer(&buffer_size),
304                            0,
305                            nullptr,
306                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
307
308  // Write from port 1 (to port 0).
309  buffer[0] = 890123456;
310  buffer[1] = 0;
311  EXPECT_EQ(MOJO_RESULT_OK,
312            mp->WriteMessage(1,
313                             UserPointer<const void>(buffer),
314                             static_cast<uint32_t>(sizeof(buffer[0])),
315                             nullptr,
316                             MOJO_WRITE_MESSAGE_FLAG_NONE));
317
318  // Read from port 0 (buffer big enough).
319  buffer[0] = 123;
320  buffer[1] = 456;
321  buffer_size = kBufferSize;
322  EXPECT_EQ(MOJO_RESULT_OK,
323            mp->ReadMessage(0,
324                            UserPointer<void>(buffer),
325                            MakeUserPointer(&buffer_size),
326                            0,
327                            nullptr,
328                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
329  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
330  EXPECT_EQ(890123456, buffer[0]);
331  EXPECT_EQ(456, buffer[1]);
332
333  // Read again from port 0 -- it should be empty.
334  buffer_size = kBufferSize;
335  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
336            mp->ReadMessage(0,
337                            UserPointer<void>(buffer),
338                            MakeUserPointer(&buffer_size),
339                            0,
340                            nullptr,
341                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
342
343  // Write from port 1 (to port 0).
344  buffer[0] = 901234567;
345  buffer[1] = 0;
346  EXPECT_EQ(MOJO_RESULT_OK,
347            mp->WriteMessage(1,
348                             UserPointer<const void>(buffer),
349                             static_cast<uint32_t>(sizeof(buffer[0])),
350                             nullptr,
351                             MOJO_WRITE_MESSAGE_FLAG_NONE));
352
353  // Read/discard from port 0 (buffer too small); get size.
354  buffer_size = 1;
355  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
356            mp->ReadMessage(0,
357                            UserPointer<void>(buffer),
358                            MakeUserPointer(&buffer_size),
359                            0,
360                            nullptr,
361                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
362  EXPECT_EQ(static_cast<uint32_t>(sizeof(buffer[0])), buffer_size);
363
364  // Read again from port 0 -- it should be empty.
365  buffer_size = kBufferSize;
366  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
367            mp->ReadMessage(0,
368                            UserPointer<void>(buffer),
369                            MakeUserPointer(&buffer_size),
370                            0,
371                            nullptr,
372                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
373
374  // Write from port 1 (to port 0).
375  buffer[0] = 123456789;
376  buffer[1] = 0;
377  EXPECT_EQ(MOJO_RESULT_OK,
378            mp->WriteMessage(1,
379                             UserPointer<const void>(buffer),
380                             static_cast<uint32_t>(sizeof(buffer[0])),
381                             nullptr,
382                             MOJO_WRITE_MESSAGE_FLAG_NONE));
383
384  // Discard from port 0.
385  buffer_size = 1;
386  EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED,
387            mp->ReadMessage(0,
388                            NullUserPointer(),
389                            NullUserPointer(),
390                            0,
391                            nullptr,
392                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
393
394  // Read again from port 0 -- it should be empty.
395  buffer_size = kBufferSize;
396  EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT,
397            mp->ReadMessage(0,
398                            UserPointer<void>(buffer),
399                            MakeUserPointer(&buffer_size),
400                            0,
401                            nullptr,
402                            MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
403
404  mp->Close(0);
405  mp->Close(1);
406}
407
408TEST(MessagePipeTest, BasicWaiting) {
409  scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
410  Waiter waiter;
411  HandleSignalsState hss;
412
413  int32_t buffer[1];
414  const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
415  uint32_t buffer_size;
416
417  // Always writable (until the other port is closed).
418  waiter.Init();
419  hss = HandleSignalsState();
420  EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
421            mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss));
422  EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
423  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
424            hss.satisfiable_signals);
425  waiter.Init();
426  hss = HandleSignalsState();
427  EXPECT_EQ(
428      MOJO_RESULT_ALREADY_EXISTS,
429      mp->AddWaiter(0,
430                    &waiter,
431                    MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
432                    0,
433                    &hss));
434  EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
435  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
436            hss.satisfiable_signals);
437
438  // Not yet readable.
439  waiter.Init();
440  ASSERT_EQ(MOJO_RESULT_OK,
441            mp->AddWaiter(0, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr));
442  EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, waiter.Wait(0, nullptr));
443  hss = HandleSignalsState();
444  mp->RemoveWaiter(0, &waiter, &hss);
445  EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals);
446  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
447            hss.satisfiable_signals);
448
449  // Write from port 0 (to port 1), to make port 1 readable.
450  buffer[0] = 123456789;
451  EXPECT_EQ(MOJO_RESULT_OK,
452            mp->WriteMessage(0,
453                             UserPointer<const void>(buffer),
454                             kBufferSize,
455                             nullptr,
456                             MOJO_WRITE_MESSAGE_FLAG_NONE));
457
458  // Port 1 should already be readable now.
459  waiter.Init();
460  hss = HandleSignalsState();
461  EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
462            mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 2, &hss));
463  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
464            hss.satisfied_signals);
465  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
466            hss.satisfiable_signals);
467  waiter.Init();
468  hss = HandleSignalsState();
469  EXPECT_EQ(
470      MOJO_RESULT_ALREADY_EXISTS,
471      mp->AddWaiter(1,
472                    &waiter,
473                    MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
474                    0,
475                    &hss));
476  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
477            hss.satisfied_signals);
478  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
479            hss.satisfiable_signals);
480  // ... and still writable.
481  waiter.Init();
482  hss = HandleSignalsState();
483  EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
484            mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 3, &hss));
485  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
486            hss.satisfied_signals);
487  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
488            hss.satisfiable_signals);
489
490  // Close port 0.
491  mp->Close(0);
492
493  // Now port 1 should not be writable.
494  waiter.Init();
495  hss = HandleSignalsState();
496  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
497            mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_WRITABLE, 4, &hss));
498  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
499  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
500
501  // But it should still be readable.
502  waiter.Init();
503  hss = HandleSignalsState();
504  EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS,
505            mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 5, &hss));
506  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals);
507  EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals);
508
509  // Read from port 1.
510  buffer[0] = 0;
511  buffer_size = kBufferSize;
512  EXPECT_EQ(MOJO_RESULT_OK,
513            mp->ReadMessage(1,
514                            UserPointer<void>(buffer),
515                            MakeUserPointer(&buffer_size),
516                            0,
517                            nullptr,
518                            MOJO_READ_MESSAGE_FLAG_NONE));
519  EXPECT_EQ(123456789, buffer[0]);
520
521  // Now port 1 should no longer be readable.
522  waiter.Init();
523  hss = HandleSignalsState();
524  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION,
525            mp->AddWaiter(1, &waiter, MOJO_HANDLE_SIGNAL_READABLE, 6, nullptr));
526  EXPECT_EQ(0u, hss.satisfied_signals);
527  EXPECT_EQ(0u, hss.satisfiable_signals);
528
529  mp->Close(1);
530}
531
532TEST(MessagePipeTest, ThreadedWaiting) {
533  int32_t buffer[1];
534  const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer));
535
536  MojoResult result;
537  uint32_t context;
538
539  // Write to wake up waiter waiting for read.
540  {
541    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
542    test::SimpleWaiterThread thread(&result, &context);
543
544    thread.waiter()->Init();
545    ASSERT_EQ(MOJO_RESULT_OK,
546              mp->AddWaiter(
547                  1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr));
548    thread.Start();
549
550    buffer[0] = 123456789;
551    // Write from port 0 (to port 1), which should wake up the waiter.
552    EXPECT_EQ(MOJO_RESULT_OK,
553              mp->WriteMessage(0,
554                               UserPointer<const void>(buffer),
555                               kBufferSize,
556                               nullptr,
557                               MOJO_WRITE_MESSAGE_FLAG_NONE));
558
559    HandleSignalsState hss;
560    mp->RemoveWaiter(1, thread.waiter(), &hss);
561    EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
562              hss.satisfied_signals);
563    EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE,
564              hss.satisfiable_signals);
565
566    mp->Close(0);
567    mp->Close(1);
568  }  // Joins |thread|.
569  // The waiter should have woken up successfully.
570  EXPECT_EQ(MOJO_RESULT_OK, result);
571  EXPECT_EQ(1u, context);
572
573  // Close to cancel waiter.
574  {
575    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
576    test::SimpleWaiterThread thread(&result, &context);
577
578    thread.waiter()->Init();
579    ASSERT_EQ(MOJO_RESULT_OK,
580              mp->AddWaiter(
581                  1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 2, nullptr));
582    thread.Start();
583
584    // Close port 1 first -- this should result in the waiter being cancelled.
585    mp->CancelAllWaiters(1);
586    mp->Close(1);
587
588    // Port 1 is closed, so |Dispatcher::RemoveWaiter()| wouldn't call into the
589    // |MessagePipe| to remove any waiter.
590
591    mp->Close(0);
592  }  // Joins |thread|.
593  EXPECT_EQ(MOJO_RESULT_CANCELLED, result);
594  EXPECT_EQ(2u, context);
595
596  // Close to make waiter un-wake-up-able.
597  {
598    scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal());
599    test::SimpleWaiterThread thread(&result, &context);
600
601    thread.waiter()->Init();
602    ASSERT_EQ(MOJO_RESULT_OK,
603              mp->AddWaiter(
604                  1, thread.waiter(), MOJO_HANDLE_SIGNAL_READABLE, 3, nullptr));
605    thread.Start();
606
607    // Close port 0 first -- this should wake the waiter up, since port 1 will
608    // never be readable.
609    mp->CancelAllWaiters(0);
610    mp->Close(0);
611
612    HandleSignalsState hss;
613    mp->RemoveWaiter(1, thread.waiter(), &hss);
614    EXPECT_EQ(0u, hss.satisfied_signals);
615    EXPECT_EQ(0u, hss.satisfiable_signals);
616
617    mp->CancelAllWaiters(1);
618    mp->Close(1);
619  }  // Joins |thread|.
620  EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result);
621  EXPECT_EQ(3u, context);
622}
623
624}  // namespace
625}  // namespace system
626}  // namespace mojo
627