| Index: mojo/edk/system/waitable_event_unittest.cc
 | 
| diff --git a/mojo/edk/system/waitable_event_unittest.cc b/mojo/edk/system/waitable_event_unittest.cc
 | 
| deleted file mode 100644
 | 
| index 80e4c9b1e5247e3a356fdbe3c3876c5bd197a8b8..0000000000000000000000000000000000000000
 | 
| --- a/mojo/edk/system/waitable_event_unittest.cc
 | 
| +++ /dev/null
 | 
| @@ -1,257 +0,0 @@
 | 
| -// Copyright 2015 The Chromium Authors. All rights reserved.
 | 
| -// Use of this source code is governed by a BSD-style license that can be
 | 
| -// found in the LICENSE file.
 | 
| -
 | 
| -#include "mojo/edk/system/waitable_event.h"
 | 
| -
 | 
| -#include <stdint.h>
 | 
| -#include <stdlib.h>
 | 
| -
 | 
| -#include <atomic>
 | 
| -#include <thread>
 | 
| -#include <type_traits>
 | 
| -#include <vector>
 | 
| -
 | 
| -#include "mojo/edk/system/test/sleep.h"
 | 
| -#include "mojo/edk/system/test/stopwatch.h"
 | 
| -#include "mojo/edk/system/test/timeouts.h"
 | 
| -#include "mojo/public/cpp/system/macros.h"
 | 
| -#include "testing/gtest/include/gtest/gtest.h"
 | 
| -
 | 
| -namespace mojo {
 | 
| -namespace system {
 | 
| -namespace {
 | 
| -
 | 
| -// Sleeps for a "very small" amount of time.
 | 
| -void EpsilonRandomSleep() {
 | 
| -  test::SleepMilliseconds(static_cast<unsigned>(rand()) % 20u);
 | 
| -}
 | 
| -
 | 
| -// We'll use |MojoDeadline| with |uint64_t| (for |WaitWithTimeout()|'s timeout
 | 
| -// argument), though note that |WaitWithTimeout()| doesn't support
 | 
| -// |MOJO_DEADLINE_INDEFINITE|.
 | 
| -static_assert(std::is_same<uint64_t, MojoDeadline>::value,
 | 
| -              "MojoDeadline isn't uint64_t!");
 | 
| -
 | 
| -// AutoResetWaitableEvent ------------------------------------------------------
 | 
| -
 | 
| -TEST(AutoResetWaitableEventTest, Basic) {
 | 
| -  AutoResetWaitableEvent ev;
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  ev.Signal();
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -  ev.Wait();
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  ev.Reset();
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  ev.Signal();
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -  ev.Reset();
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  EXPECT_TRUE(ev.WaitWithTimeout(0));
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  EXPECT_TRUE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1)));
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  ev.Signal();
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -  EXPECT_FALSE(ev.WaitWithTimeout(0));
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  EXPECT_TRUE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1)));
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  ev.Signal();
 | 
| -  EXPECT_FALSE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1)));
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -}
 | 
| -
 | 
| -TEST(AutoResetWaitableEventTest, MultipleWaiters) {
 | 
| -  AutoResetWaitableEvent ev;
 | 
| -
 | 
| -  for (size_t i = 0u; i < 5u; i++) {
 | 
| -    std::atomic_uint wake_count(0u);
 | 
| -    std::vector<std::thread> threads;
 | 
| -    for (size_t j = 0u; j < 4u; j++) {
 | 
| -      threads.push_back(std::thread([&ev, &wake_count]() {
 | 
| -        if (rand() % 2 == 0)
 | 
| -          ev.Wait();
 | 
| -        else
 | 
| -          EXPECT_FALSE(ev.WaitWithTimeout(test::ActionTimeout()));
 | 
| -        wake_count.fetch_add(1u);
 | 
| -        // Note: We can't say anything about the signaled state of |ev| here,
 | 
| -        // since the main thread may have already signaled it again.
 | 
| -      }));
 | 
| -    }
 | 
| -
 | 
| -    // Unfortunately, we can't really wait for the threads to be waiting, so we
 | 
| -    // just sleep for a bit, and count on them having started and advanced to
 | 
| -    // waiting.
 | 
| -    test::Sleep(2 * test::TinyTimeout());
 | 
| -
 | 
| -    for (size_t j = 0u; j < threads.size(); j++) {
 | 
| -      unsigned old_wake_count = wake_count.load();
 | 
| -      EXPECT_EQ(j, old_wake_count);
 | 
| -
 | 
| -      // Each |Signal()| should wake exactly one thread.
 | 
| -      ev.Signal();
 | 
| -
 | 
| -      // Poll for |wake_count| to change.
 | 
| -      while (wake_count.load() == old_wake_count)
 | 
| -        test::Sleep(test::EpsilonTimeout());
 | 
| -
 | 
| -      EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -
 | 
| -      // And once it's changed, wait a little longer, to see if any other
 | 
| -      // threads are awoken (they shouldn't be).
 | 
| -      test::Sleep(test::EpsilonTimeout());
 | 
| -
 | 
| -      EXPECT_EQ(old_wake_count + 1u, wake_count.load());
 | 
| -
 | 
| -      EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -    }
 | 
| -
 | 
| -    // Having done that, if we signal |ev| now, it should stay signaled.
 | 
| -    ev.Signal();
 | 
| -    test::Sleep(test::EpsilonTimeout());
 | 
| -    EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -
 | 
| -    for (auto& thread : threads)
 | 
| -      thread.join();
 | 
| -
 | 
| -    ev.Reset();
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -TEST(AutoResetWaitableEventTest, Timeouts) {
 | 
| -  static const unsigned kTestTimeoutsMs[] = {0, 10, 20, 40, 80};
 | 
| -
 | 
| -  test::Stopwatch stopwatch;
 | 
| -
 | 
| -  AutoResetWaitableEvent ev;
 | 
| -
 | 
| -  for (size_t i = 0u; i < MOJO_ARRAYSIZE(kTestTimeoutsMs); i++) {
 | 
| -    uint64_t timeout = test::DeadlineFromMilliseconds(kTestTimeoutsMs[i]);
 | 
| -
 | 
| -    stopwatch.Start();
 | 
| -    EXPECT_TRUE(ev.WaitWithTimeout(timeout));
 | 
| -    MojoDeadline elapsed = stopwatch.Elapsed();
 | 
| -
 | 
| -    // It should time out after *at least* the specified amount of time.
 | 
| -    EXPECT_GE(elapsed, timeout);
 | 
| -    // But we expect that it should time out soon after that amount of time.
 | 
| -    EXPECT_LT(elapsed, timeout + test::EpsilonTimeout());
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -// ManualResetWaitableEvent ----------------------------------------------------
 | 
| -
 | 
| -TEST(ManualResetWaitableEventTest, Basic) {
 | 
| -  ManualResetWaitableEvent ev;
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  ev.Signal();
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -  ev.Wait();
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -  ev.Reset();
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  EXPECT_TRUE(ev.WaitWithTimeout(0));
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  EXPECT_TRUE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1)));
 | 
| -  EXPECT_FALSE(ev.IsSignaledForTest());
 | 
| -  ev.Signal();
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -  EXPECT_FALSE(ev.WaitWithTimeout(0));
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -  EXPECT_FALSE(ev.WaitWithTimeout(test::DeadlineFromMilliseconds(1)));
 | 
| -  EXPECT_TRUE(ev.IsSignaledForTest());
 | 
| -}
 | 
| -
 | 
| -TEST(ManualResetWaitableEventTest, SignalMultiple) {
 | 
| -  ManualResetWaitableEvent ev;
 | 
| -
 | 
| -  for (size_t i = 0u; i < 10u; i++) {
 | 
| -    for (size_t num_waiters = 1u; num_waiters < 5u; num_waiters++) {
 | 
| -      std::vector<std::thread> threads;
 | 
| -      for (size_t j = 0u; j < num_waiters; j++) {
 | 
| -        threads.push_back(std::thread([&ev]() {
 | 
| -          EpsilonRandomSleep();
 | 
| -
 | 
| -          if (rand() % 2 == 0)
 | 
| -            ev.Wait();
 | 
| -          else
 | 
| -            EXPECT_FALSE(ev.WaitWithTimeout(test::ActionTimeout()));
 | 
| -        }));
 | 
| -      }
 | 
| -
 | 
| -      EpsilonRandomSleep();
 | 
| -
 | 
| -      ev.Signal();
 | 
| -
 | 
| -      // The threads will only terminate once they've successfully waited (or
 | 
| -      // timed out).
 | 
| -      for (auto& thread : threads)
 | 
| -        thread.join();
 | 
| -
 | 
| -      ev.Reset();
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -// Tries to test that threads that are awoken may immediately call |Reset()|
 | 
| -// without affecting other threads that are awoken.
 | 
| -TEST(ManualResetWaitableEventTest, SignalMultipleWaitReset) {
 | 
| -  ManualResetWaitableEvent ev;
 | 
| -
 | 
| -  for (size_t i = 0u; i < 5u; i++) {
 | 
| -    std::vector<std::thread> threads;
 | 
| -    for (size_t j = 0u; j < 4u; j++) {
 | 
| -      threads.push_back(std::thread([&ev]() {
 | 
| -        if (rand() % 2 == 0)
 | 
| -          ev.Wait();
 | 
| -        else
 | 
| -          EXPECT_FALSE(ev.WaitWithTimeout(test::ActionTimeout()));
 | 
| -        ev.Reset();
 | 
| -      }));
 | 
| -    }
 | 
| -
 | 
| -    // Unfortunately, we can't really wait for the threads to be waiting, so we
 | 
| -    // just sleep for a bit, and count on them having started and advanced to
 | 
| -    // waiting.
 | 
| -    test::Sleep(2 * test::TinyTimeout());
 | 
| -
 | 
| -    ev.Signal();
 | 
| -
 | 
| -    // In fact, we may ourselves call |Reset()| immediately.
 | 
| -    ev.Reset();
 | 
| -
 | 
| -    // The threads will only terminate once they've successfully waited (or
 | 
| -    // timed out).
 | 
| -    for (auto& thread : threads)
 | 
| -      thread.join();
 | 
| -
 | 
| -    ASSERT_FALSE(ev.IsSignaledForTest());
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -TEST(ManualResetWaitableEventTest, Timeouts) {
 | 
| -  static const unsigned kTestTimeoutsMs[] = {0, 10, 20, 40, 80};
 | 
| -
 | 
| -  test::Stopwatch stopwatch;
 | 
| -
 | 
| -  ManualResetWaitableEvent ev;
 | 
| -
 | 
| -  for (size_t i = 0u; i < MOJO_ARRAYSIZE(kTestTimeoutsMs); i++) {
 | 
| -    uint64_t timeout = test::DeadlineFromMilliseconds(kTestTimeoutsMs[i]);
 | 
| -
 | 
| -    stopwatch.Start();
 | 
| -    EXPECT_TRUE(ev.WaitWithTimeout(timeout));
 | 
| -    MojoDeadline elapsed = stopwatch.Elapsed();
 | 
| -
 | 
| -    // It should time out after *at least* the specified amount of time.
 | 
| -    EXPECT_GE(elapsed, timeout);
 | 
| -    // But we expect that it should time out soon after that amount of time.
 | 
| -    EXPECT_LT(elapsed, timeout + test::EpsilonTimeout());
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -}  // namespace
 | 
| -}  // namespace system
 | 
| -}  // namespace mojo
 | 
| 
 |