tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

testThreadingConditionVariable.cpp (6300B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 * vim: set ts=8 sts=2 et sw=2 tw=80:
      3 */
      4 /* This Source Code Form is subject to the terms of the Mozilla Public
      5 * License, v. 2.0. If a copy of the MPL was not distributed with this
      6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      7 
      8 #include "jsapi-tests/tests.h"
      9 #include "threading/ConditionVariable.h"
     10 #include "threading/Thread.h"
     11 #include "vm/MutexIDs.h"
     12 
     13 struct TestState {
     14  js::Mutex mutex MOZ_UNANNOTATED;
     15  js::ConditionVariable condition;
     16  bool flag;
     17  js::Thread testThread;
     18 
     19  explicit TestState(bool createThread = true)
     20      : mutex(js::mutexid::TestMutex), flag(false) {
     21    if (createThread) {
     22      MOZ_RELEASE_ASSERT(testThread.init(setFlag, this));
     23    }
     24  }
     25 
     26  static void setFlag(TestState* state) {
     27    js::UniqueLock<js::Mutex> lock(state->mutex);
     28    state->flag = true;
     29    state->condition.notify_one();
     30  }
     31 
     32  void join() { testThread.join(); }
     33 };
     34 
     35 BEGIN_TEST(testThreadingConditionVariable) {
     36  auto state = mozilla::MakeUnique<TestState>();
     37  {
     38    js::UniqueLock<js::Mutex> lock(state->mutex);
     39    while (!state->flag) {
     40      state->condition.wait(lock);
     41    }
     42  }
     43  state->join();
     44 
     45  CHECK(state->flag);
     46 
     47  return true;
     48 }
     49 END_TEST(testThreadingConditionVariable)
     50 
     51 BEGIN_TEST(testThreadingConditionVariablePredicate) {
     52  auto state = mozilla::MakeUnique<TestState>();
     53  {
     54    js::UniqueLock<js::Mutex> lock(state->mutex);
     55    state->condition.wait(lock, [&state]() { return state->flag; });
     56  }
     57  state->join();
     58 
     59  CHECK(state->flag);
     60 
     61  return true;
     62 }
     63 END_TEST(testThreadingConditionVariablePredicate)
     64 
     65 BEGIN_TEST(testThreadingConditionVariableUntilOkay) {
     66  auto state = mozilla::MakeUnique<TestState>();
     67  {
     68    js::UniqueLock<js::Mutex> lock(state->mutex);
     69    while (!state->flag) {
     70      auto to =
     71          mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromSeconds(600);
     72      js::CVStatus res = state->condition.wait_until(lock, to);
     73      CHECK(res == js::CVStatus::NoTimeout);
     74    }
     75  }
     76  state->join();
     77 
     78  CHECK(state->flag);
     79 
     80  return true;
     81 }
     82 END_TEST(testThreadingConditionVariableUntilOkay)
     83 
     84 BEGIN_TEST(testThreadingConditionVariableUntilTimeout) {
     85  auto state = mozilla::MakeUnique<TestState>(false);
     86  {
     87    js::UniqueLock<js::Mutex> lock(state->mutex);
     88    while (!state->flag) {
     89      auto to = mozilla::TimeStamp::Now() +
     90                mozilla::TimeDuration::FromMilliseconds(10);
     91      js::CVStatus res = state->condition.wait_until(lock, to);
     92      if (res == js::CVStatus::Timeout) {
     93        break;
     94      }
     95    }
     96  }
     97  CHECK(!state->flag);
     98 
     99  // Timeout in the past should return with timeout immediately.
    100  {
    101    js::UniqueLock<js::Mutex> lock(state->mutex);
    102    auto to =
    103        mozilla::TimeStamp::Now() - mozilla::TimeDuration::FromMilliseconds(10);
    104    js::CVStatus res = state->condition.wait_until(lock, to);
    105    CHECK(res == js::CVStatus::Timeout);
    106  }
    107 
    108  return true;
    109 }
    110 END_TEST(testThreadingConditionVariableUntilTimeout)
    111 
    112 BEGIN_TEST(testThreadingConditionVariableUntilOkayPredicate) {
    113  auto state = mozilla::MakeUnique<TestState>();
    114  {
    115    js::UniqueLock<js::Mutex> lock(state->mutex);
    116    auto to =
    117        mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromSeconds(600);
    118    bool res = state->condition.wait_until(lock, to,
    119                                           [&state]() { return state->flag; });
    120    CHECK(res);
    121  }
    122  state->join();
    123 
    124  CHECK(state->flag);
    125 
    126  return true;
    127 }
    128 END_TEST(testThreadingConditionVariableUntilOkayPredicate)
    129 
    130 BEGIN_TEST(testThreadingConditionVariableUntilTimeoutPredicate) {
    131  auto state = mozilla::MakeUnique<TestState>(false);
    132  {
    133    js::UniqueLock<js::Mutex> lock(state->mutex);
    134    auto to =
    135        mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromMilliseconds(10);
    136    bool res = state->condition.wait_until(lock, to,
    137                                           [&state]() { return state->flag; });
    138    CHECK(!res);
    139  }
    140  CHECK(!state->flag);
    141 
    142  return true;
    143 }
    144 END_TEST(testThreadingConditionVariableUntilTimeoutPredicate)
    145 
    146 BEGIN_TEST(testThreadingConditionVariableForOkay) {
    147  auto state = mozilla::MakeUnique<TestState>();
    148  {
    149    js::UniqueLock<js::Mutex> lock(state->mutex);
    150    while (!state->flag) {
    151      auto duration = mozilla::TimeDuration::FromSeconds(600);
    152      js::CVStatus res = state->condition.wait_for(lock, duration);
    153      CHECK(res == js::CVStatus::NoTimeout);
    154    }
    155  }
    156  state->join();
    157 
    158  CHECK(state->flag);
    159 
    160  return true;
    161 }
    162 END_TEST(testThreadingConditionVariableForOkay)
    163 
    164 BEGIN_TEST(testThreadingConditionVariableForTimeout) {
    165  auto state = mozilla::MakeUnique<TestState>(false);
    166  {
    167    js::UniqueLock<js::Mutex> lock(state->mutex);
    168    while (!state->flag) {
    169      auto duration = mozilla::TimeDuration::FromMilliseconds(10);
    170      js::CVStatus res = state->condition.wait_for(lock, duration);
    171      if (res == js::CVStatus::Timeout) {
    172        break;
    173      }
    174    }
    175  }
    176  CHECK(!state->flag);
    177 
    178  // Timeout in the past should return with timeout immediately.
    179  {
    180    js::UniqueLock<js::Mutex> lock(state->mutex);
    181    auto duration = mozilla::TimeDuration::FromMilliseconds(-10);
    182    js::CVStatus res = state->condition.wait_for(lock, duration);
    183    CHECK(res == js::CVStatus::Timeout);
    184  }
    185 
    186  return true;
    187 }
    188 END_TEST(testThreadingConditionVariableForTimeout)
    189 
    190 BEGIN_TEST(testThreadingConditionVariableForOkayPredicate) {
    191  auto state = mozilla::MakeUnique<TestState>();
    192  {
    193    js::UniqueLock<js::Mutex> lock(state->mutex);
    194    auto duration = mozilla::TimeDuration::FromSeconds(600);
    195    bool res = state->condition.wait_for(lock, duration,
    196                                         [&state]() { return state->flag; });
    197    CHECK(res);
    198  }
    199  state->join();
    200 
    201  CHECK(state->flag);
    202 
    203  return true;
    204 }
    205 END_TEST(testThreadingConditionVariableForOkayPredicate)
    206 
    207 BEGIN_TEST(testThreadingConditionVariableForTimeoutPredicate) {
    208  auto state = mozilla::MakeUnique<TestState>(false);
    209  {
    210    js::UniqueLock<js::Mutex> lock(state->mutex);
    211    auto duration = mozilla::TimeDuration::FromMilliseconds(10);
    212    bool res = state->condition.wait_for(lock, duration,
    213                                         [&state]() { return state->flag; });
    214    CHECK(!res);
    215  }
    216  CHECK(!state->flag);
    217 
    218  return true;
    219 }
    220 END_TEST(testThreadingConditionVariableForTimeoutPredicate)