14e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file. 44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 54e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// NOTE(vtl): Some of these tests are inherently flaky (e.g., if run on a 6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// heavily-loaded system). Sorry. |test::EpsilonTimeout()| may be increased to 7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// increase tolerance and reduce observed flakiness (though doing so reduces the 8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// meaningfulness of the test). 94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/message_pipe_dispatcher.h" 114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <string.h> 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <limits> 154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/ref_counted.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/memory/scoped_vector.h" 184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/rand_util.h" 194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/platform_thread.h" // For |Sleep()|. 204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/threading/simple_thread.h" 214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/time/time.h" 224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/message_pipe.h" 234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/test_utils.h" 244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/waiter.h" 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "mojo/system/waiter_test_utils.h" 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace mojo { 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace system { 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)namespace { 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(MessagePipeDispatcherTest, Basic) { 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) test::Stopwatch stopwatch; 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int32_t buffer[1]; 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t buffer_size; 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Run this test both with |d0| as port 0, |d1| as port 1 and vice versa. 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned i = 0; i < 2; i++) { 40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d0(new MessagePipeDispatcher( 41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(Dispatcher::kTypeMessagePipe, d0->GetType()); 43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d1(new MessagePipeDispatcher( 44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->Init(mp, i); // 0, 1. 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d1->Init(mp, i ^ 1); // 1, 0. 494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Waiter w; 51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uint32_t context = 0; 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HandleSignalsState hss; 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Try adding a writable waiter when already writable. 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 0, &hss)); 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Shouldn't need to remove the waiter (it was not added). 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add a readable waiter to |d0|, then make it readable (by writing to 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // |d1|), then wait. 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(MOJO_RESULT_OK, 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 1, nullptr)); 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 123456789; 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d1->WriteMessage(UserPointer<const void>(buffer), 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kBufferSize, 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, &context)); 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(1u, context); 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout()); 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->RemoveWaiter(&w, &hss); 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfied_signals); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Try adding a readable waiter when already readable (from above). 874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 2, &hss)); 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfied_signals); 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Shouldn't need to remove the waiter (it was not added). 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Make |d0| no longer readable (by reading from it). 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 0; 994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer_size = kBufferSize; 1004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->ReadMessage(UserPointer<void>(buffer), 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE)); 1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(kBufferSize, buffer_size); 1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(123456789, buffer[0]); 1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Wait for zero time for readability on |d0| (will time out). 1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(MOJO_RESULT_OK, 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 3, nullptr)); 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, w.Wait(0, nullptr)); 115cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout()); 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->RemoveWaiter(&w, &hss); 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Wait for non-zero, finite time for readability on |d0| (will time out). 1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ASSERT_EQ(MOJO_RESULT_OK, 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 3, nullptr)); 1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_DEADLINE_EXCEEDED, 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci w.Wait(2 * test::EpsilonTimeout().InMicroseconds(), nullptr)); 129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta elapsed = stopwatch.Elapsed(); 1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout()); 1315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout()); 1325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->RemoveWaiter(&w, &hss); 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_WRITABLE, hss.satisfied_signals); 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d0->Close()); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d1->Close()); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(MessagePipeDispatcherTest, InvalidParams) { 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) char buffer[1]; 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d0( 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d1( 1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); 1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d0->Init(mp, 0); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d1->Init(mp, 1); 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |WriteMessage|: 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Huge buffer size. 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_RESOURCE_EXHAUSTED, 1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->WriteMessage(UserPointer<const void>(buffer), 1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::numeric_limits<uint32_t>::max(), 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 1634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d0->Close()); 1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d1->Close()); 1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// These test invalid arguments that should cause death if we're being paranoid 1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// about checking arguments (which we would want to do if, e.g., we were in a 1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// true "kernel" situation, but we might not want to do otherwise for 1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// performance reasons). Probably blatant errors like passing in null pointers 1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// (for required pointer arguments) will still cause death, but perhaps not 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// predictably. 1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(MessagePipeDispatcherTest, InvalidParamsDeath) { 1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const char kMemoryCheckFailedRegex[] = "Check failed"; 1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d0( 1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); 1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d1( 1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); 1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) { 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); 1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->Init(mp, 0); 1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d1->Init(mp, 1); 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |WriteMessage|: 1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Null buffer with nonzero buffer size. 1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_DEATH_IF_SUPPORTED( 1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->WriteMessage( 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NullUserPointer(), 1, nullptr, MOJO_WRITE_MESSAGE_FLAG_NONE), 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kMemoryCheckFailedRegex); 1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |ReadMessage|: 1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Null buffer with nonzero buffer size. 1965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // First write something so that we actually have something to read. 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(MOJO_RESULT_OK, 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci d1->WriteMessage(UserPointer<const void>("x"), 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1, 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MOJO_WRITE_MESSAGE_FLAG_NONE)); 2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t buffer_size = 1; 2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_DEATH_IF_SUPPORTED(d0->ReadMessage(NullUserPointer(), 2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE), 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kMemoryCheckFailedRegex); 2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d0->Close()); 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d1->Close()); 2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Test what happens when one end is closed (single-threaded test). 2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(MessagePipeDispatcherTest, BasicClosed) { 2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int32_t buffer[1]; 2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); 2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t buffer_size; 2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Run this test both with |d0| as port 0, |d1| as port 1 and vice versa. 2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned i = 0; i < 2; i++) { 222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d0(new MessagePipeDispatcher( 223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d1(new MessagePipeDispatcher( 225f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); 2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->Init(mp, i); // 0, 1. 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d1->Init(mp, i ^ 1); // 1, 0. 2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Waiter w; 2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HandleSignalsState hss; 2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Write (twice) to |d1|. 2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 123456789; 2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d1->WriteMessage(UserPointer<const void>(buffer), 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kBufferSize, 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 234567890; 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d1->WriteMessage(UserPointer<const void>(buffer), 2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kBufferSize, 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try waiting for readable on |d0|; should fail (already satisfied). 2494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss)); 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfied_signals); 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try reading from |d1|; should fail (nothing to read). 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer[0] = 0; 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) buffer_size = kBufferSize; 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_SHOULD_WAIT, 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d1->ReadMessage(UserPointer<void>(buffer), 2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE)); 267f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Close |d1|. 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d1->Close()); 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try waiting for readable on |d0|; should fail (already satisfied). 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, 2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 1, &hss)); 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); 2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Read from |d0|. 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 0; 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer_size = kBufferSize; 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->ReadMessage(UserPointer<void>(buffer), 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE)); 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(kBufferSize, buffer_size); 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(123456789, buffer[0]); 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try waiting for readable on |d0|; should fail (already satisfied). 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, 2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 2, &hss)); 2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfied_signals); 2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE, hss.satisfiable_signals); 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Read again from |d0|. 3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 0; 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer_size = kBufferSize; 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->ReadMessage(UserPointer<void>(buffer), 3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE)); 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(kBufferSize, buffer_size); 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(234567890, buffer[0]); 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try waiting for readable on |d0|; should fail (unsatisfiable). 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 3144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 3, &hss)); 3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfied_signals); 3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfiable_signals); 3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try waiting for writable on |d0|; should fail (unsatisfiable). 3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->AddWaiter(&w, MOJO_HANDLE_SIGNAL_WRITABLE, 4, &hss)); 3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfied_signals); 3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfiable_signals); 3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try reading from |d0|; should fail (nothing to read and other end 328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // closed). 3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 0; 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer_size = kBufferSize; 331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->ReadMessage(UserPointer<void>(buffer), 3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE)); 3374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Try writing to |d0|; should fail (other end closed). 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 345678901; 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, 3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->WriteMessage(UserPointer<const void>(buffer), 3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kBufferSize, 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d0->Close()); 3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_WIN) 3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// http://crbug.com/396386 3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define MAYBE_BasicThreaded DISABLED_BasicThreaded 3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define MAYBE_BasicThreaded BasicThreaded 3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST(MessagePipeDispatcherTest, MAYBE_BasicThreaded) { 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) test::Stopwatch stopwatch; 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int32_t buffer[1]; 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const uint32_t kBufferSize = static_cast<uint32_t>(sizeof(buffer)); 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t buffer_size; 361cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::TimeDelta elapsed; 3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool did_wait; 3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MojoResult result; 364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) uint32_t context; 3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HandleSignalsState hss; 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Run this test both with |d0| as port 0, |d1| as port 1 and vice versa. 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned i = 0; i < 2; i++) { 369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d0(new MessagePipeDispatcher( 370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d1(new MessagePipeDispatcher( 372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); 3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->Init(mp, i); // 0, 1. 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d1->Init(mp, i ^ 1); // 1, 0. 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Wait for readable on |d1|, which will become readable after some time. 3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test::WaiterThread thread(d1, 3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_HANDLE_SIGNAL_READABLE, 3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MOJO_DEADLINE_INDEFINITE, 3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1, 3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &did_wait, 3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &result, 3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &context, 3885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &hss); 3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Wake it up by writing to |d0|. 3934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 123456789; 3944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 3955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->WriteMessage(UserPointer<const void>(buffer), 3965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kBufferSize, 3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } // Joins the thread. 400cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed = stopwatch.Elapsed(); 4015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout()); 4025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout()); 4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(did_wait); 404f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, result); 405f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(1u, context); 4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfied_signals); 4085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 4095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Now |d1| is already readable. Try waiting for it again. 4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test::WaiterThread thread(d1, 414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MOJO_HANDLE_SIGNAL_READABLE, 4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MOJO_DEADLINE_INDEFINITE, 416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 2, 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &did_wait, 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &result, 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &context, 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &hss); 4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 4224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 4234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } // Joins the thread. 424cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) EXPECT_LT(stopwatch.Elapsed(), test::EpsilonTimeout()); 4254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_FALSE(did_wait); 4264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_ALREADY_EXISTS, result); 4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 4285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfied_signals); 4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_WRITABLE, 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss.satisfiable_signals); 4314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Consume what we wrote to |d0|. 4334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[0] = 0; 4344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer_size = kBufferSize; 4354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d1->ReadMessage(UserPointer<void>(buffer), 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 4385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE)); 4414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(kBufferSize, buffer_size); 4424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(123456789, buffer[0]); 4434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Wait for readable on |d1| and close |d0| after some time, which should 4454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // cancel that wait. 4464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test::WaiterThread thread(d1, 448f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MOJO_HANDLE_SIGNAL_READABLE, 4494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MOJO_DEADLINE_INDEFINITE, 450f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 3, 4515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &did_wait, 4525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &result, 4535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &context, 4545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &hss); 4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 4564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d0->Close()); 4594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } // Joins the thread. 460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed = stopwatch.Elapsed(); 4615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout()); 4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout()); 4634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(did_wait); 4644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_FAILED_PRECONDITION, result); 465f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(3u, context); 4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfied_signals); 4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfiable_signals); 4684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d1->Close()); 4704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (unsigned i = 0; i < 2; i++) { 473f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d0(new MessagePipeDispatcher( 474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 475f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d1(new MessagePipeDispatcher( 476f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MessagePipeDispatcher::kDefaultCreateOptions)); 4774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) d0->Init(mp, i); // 0, 1. 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d1->Init(mp, i ^ 1); // 1, 0. 4814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 4824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Wait for readable on |d1| and close |d1| after some time, which should 4844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // cancel that wait. 4854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) test::WaiterThread thread(d1, 487f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MOJO_HANDLE_SIGNAL_READABLE, 4884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MOJO_DEADLINE_INDEFINITE, 489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 4, 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &did_wait, 4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &result, 4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &context, 4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &hss); 4944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) stopwatch.Start(); 4954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) thread.Start(); 496cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::PlatformThread::Sleep(2 * test::EpsilonTimeout()); 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d1->Close()); 4984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } // Joins the thread. 499cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) elapsed = stopwatch.Elapsed(); 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_GT(elapsed, (2 - 1) * test::EpsilonTimeout()); 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_LT(elapsed, (2 + 1) * test::EpsilonTimeout()); 5024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(did_wait); 5034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_CANCELLED, result); 504f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) EXPECT_EQ(4u, context); 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfied_signals); 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(0u, hss.satisfiable_signals); 5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d0->Close()); 5094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 5114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Stress test ----------------------------------------------------------------- 5134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const size_t kMaxMessageSize = 2000; 5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class WriterThread : public base::SimpleThread { 5174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 5184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |*messages_written| and |*bytes_written| belong to the thread while it's 5194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // alive. 5204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) WriterThread(scoped_refptr<Dispatcher> write_dispatcher, 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* messages_written, 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* bytes_written) 5234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : base::SimpleThread("writer_thread"), 5244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) write_dispatcher_(write_dispatcher), 5254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) messages_written_(messages_written), 5264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bytes_written_(bytes_written) { 5274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *messages_written_ = 0; 5284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *bytes_written_ = 0; 5294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual ~WriterThread() { Join(); } 5324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 5344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Run() OVERRIDE { 5354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Make some data to write. 5364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char buffer[kMaxMessageSize]; 5374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kMaxMessageSize; i++) 5384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) buffer[i] = static_cast<unsigned char>(i); 5394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Number of messages to write. 5414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *messages_written_ = static_cast<size_t>(base::RandInt(1000, 6000)); 5424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Write messages. 5444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < *messages_written_; i++) { 5454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t bytes_to_write = static_cast<uint32_t>( 5464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::RandInt(1, static_cast<int>(kMaxMessageSize))); 5474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) write_dispatcher_->WriteMessage(UserPointer<const void>(buffer), 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bytes_to_write, 5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 5514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 5524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *bytes_written_ += bytes_to_write; 5534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Write one last "quit" message. 5564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, 5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) write_dispatcher_->WriteMessage(UserPointer<const void>("quit"), 5585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4, 5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE)); 5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<Dispatcher> write_dispatcher_; 5644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t* const messages_written_; 5654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t* const bytes_written_; 5664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(WriterThread); 5684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 5694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class ReaderThread : public base::SimpleThread { 5714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public: 5724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // |*messages_read| and |*bytes_read| belong to the thread while it's alive. 5734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ReaderThread(scoped_refptr<Dispatcher> read_dispatcher, 5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* messages_read, 5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) size_t* bytes_read) 5764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) : base::SimpleThread("reader_thread"), 5774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) read_dispatcher_(read_dispatcher), 5784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) messages_read_(messages_read), 5794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bytes_read_(bytes_read) { 5804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *messages_read_ = 0; 5814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *bytes_read_ = 0; 5824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 5834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) virtual ~ReaderThread() { Join(); } 5854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private: 5874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) virtual void Run() OVERRIDE { 5884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) unsigned char buffer[kMaxMessageSize]; 5894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Waiter w; 5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) HandleSignalsState hss; 5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MojoResult result; 5924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 5934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Read messages. 5944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (;;) { 5954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Wait for it to be readable. 5964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) w.Init(); 5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) hss = HandleSignalsState(); 5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = 5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) read_dispatcher_->AddWaiter(&w, MOJO_HANDLE_SIGNAL_READABLE, 0, &hss); 6004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(result == MOJO_RESULT_OK || 6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result == MOJO_RESULT_ALREADY_EXISTS) 6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << "result: " << result; 6034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (result == MOJO_RESULT_OK) { 6044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Actually need to wait. 6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(MOJO_RESULT_OK, w.Wait(MOJO_DEADLINE_INDEFINITE, nullptr)); 6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) read_dispatcher_->RemoveWaiter(&w, &hss); 6074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // We may not actually be readable, since we're racing with other threads. 6095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE((hss.satisfiable_signals & MOJO_HANDLE_SIGNAL_READABLE)); 6104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Now, try to do the read. 6124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Clear the buffer so that we can check the result. 6134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) memset(buffer, 0, sizeof(buffer)); 6144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t buffer_size = static_cast<uint32_t>(sizeof(buffer)); 6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) result = read_dispatcher_->ReadMessage(UserPointer<void>(buffer), 6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) MakeUserPointer(&buffer_size), 6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0, 6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci nullptr, 6194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE); 6205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(result == MOJO_RESULT_OK || result == MOJO_RESULT_SHOULD_WAIT) 6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << "result: " << result; 6224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We're racing with others to read, so maybe we failed. 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result == MOJO_RESULT_SHOULD_WAIT) 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) continue; // In which case, try again. 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check for quit. 6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (buffer_size == 4 && memcmp("quit", buffer, 4) == 0) 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GE(buffer_size, 1u); 6294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_LE(buffer_size, kMaxMessageSize); 6304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_TRUE(IsValidMessage(buffer, buffer_size)); 6314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) (*messages_read_)++; 6334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) *bytes_read_ += buffer_size; 6344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static bool IsValidMessage(const unsigned char* buffer, 6384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) uint32_t message_size) { 6394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t i; 6404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (i = 0; i < message_size; i++) { 6414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (buffer[i] != static_cast<unsigned char>(i)) 6424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 6434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Check that the remaining bytes weren't stomped on. 6454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (; i < kMaxMessageSize; i++) { 6464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (buffer[i] != 0) 6474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return false; 6484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return true; 6504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const scoped_refptr<Dispatcher> read_dispatcher_; 6534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t* const messages_read_; 6544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t* const bytes_read_; 6554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(ReaderThread); 6574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}; 6584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)TEST(MessagePipeDispatcherTest, Stress) { 6604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const size_t kNumWriters = 30; 6614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) static const size_t kNumReaders = kNumWriters; 6624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d_write( 6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); 6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<MessagePipeDispatcher> d_read( 6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new MessagePipeDispatcher(MessagePipeDispatcher::kDefaultCreateOptions)); 6674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 6681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_refptr<MessagePipe> mp(MessagePipe::CreateLocalLocal()); 6694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) d_write->Init(mp, 0); 6704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) d_read->Init(mp, 1); 6714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t messages_written[kNumWriters]; 6744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t bytes_written[kNumWriters]; 6754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t messages_read[kNumReaders]; 6764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t bytes_read[kNumReaders]; 6774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { 6784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Make writers. 6794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedVector<WriterThread> writers; 6804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kNumWriters; i++) { 6814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) writers.push_back( 6824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new WriterThread(d_write, &messages_written[i], &bytes_written[i])); 6834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Make readers. 6864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedVector<ReaderThread> readers; 6874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kNumReaders; i++) { 6884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) readers.push_back( 6894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) new ReaderThread(d_read, &messages_read[i], &bytes_read[i])); 6904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 6914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Start writers. 6934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kNumWriters; i++) 6944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) writers[i]->Start(); 6954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 6964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Start readers. 6974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kNumReaders; i++) 6984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) readers[i]->Start(); 6994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // TODO(vtl): Maybe I should have an event that triggers all the threads to 7014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // start doing stuff for real (so that the first ones created/started aren't 7024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // advantaged). 7034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } // Joins all the threads. 7044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t total_messages_written = 0; 7064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t total_bytes_written = 0; 7074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kNumWriters; i++) { 7084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) total_messages_written += messages_written[i]; 7094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) total_bytes_written += bytes_written[i]; 7104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t total_messages_read = 0; 7124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) size_t total_bytes_read = 0; 7134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) for (size_t i = 0; i < kNumReaders; i++) { 7144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) total_messages_read += messages_read[i]; 7154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) total_bytes_read += bytes_read[i]; 7164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // We'd have to be really unlucky to have read no messages on a thread. 7174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GT(messages_read[i], 0u) << "reader: " << i; 7184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_GE(bytes_read[i], messages_read[i]) << "reader: " << i; 7194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 7204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(total_messages_written, total_messages_read); 7214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(total_bytes_written, total_bytes_read); 7224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d_write->Close()); 7244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) EXPECT_EQ(MOJO_RESULT_OK, d_read->Close()); 7254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 7264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 7274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace 7284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace system 7294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} // namespace mojo 730