Home | History | Annotate | Download | only in system
      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
     30 TEST(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 
    236 TEST(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 
    270 TEST(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 
    408 TEST(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 
    532 TEST(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