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(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 
    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 
    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 
    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 
    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