diff options
Diffstat (limited to 'js/src/jsapi-tests/testThreadingConditionVariable.cpp')
-rw-r--r-- | js/src/jsapi-tests/testThreadingConditionVariable.cpp | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/js/src/jsapi-tests/testThreadingConditionVariable.cpp b/js/src/jsapi-tests/testThreadingConditionVariable.cpp new file mode 100644 index 0000000000..1bff194372 --- /dev/null +++ b/js/src/jsapi-tests/testThreadingConditionVariable.cpp @@ -0,0 +1,220 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * vim: set ts=8 sts=2 et sw=2 tw=80: + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "jsapi-tests/tests.h" +#include "threading/ConditionVariable.h" +#include "threading/Thread.h" +#include "vm/MutexIDs.h" + +struct TestState { + js::Mutex mutex MOZ_UNANNOTATED; + js::ConditionVariable condition; + bool flag; + js::Thread testThread; + + explicit TestState(bool createThread = true) + : mutex(js::mutexid::TestMutex), flag(false) { + if (createThread) { + MOZ_RELEASE_ASSERT(testThread.init(setFlag, this)); + } + } + + static void setFlag(TestState* state) { + js::UniqueLock<js::Mutex> lock(state->mutex); + state->flag = true; + state->condition.notify_one(); + } + + void join() { testThread.join(); } +}; + +BEGIN_TEST(testThreadingConditionVariable) { + auto state = mozilla::MakeUnique<TestState>(); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + while (!state->flag) { + state->condition.wait(lock); + } + } + state->join(); + + CHECK(state->flag); + + return true; +} +END_TEST(testThreadingConditionVariable) + +BEGIN_TEST(testThreadingConditionVariablePredicate) { + auto state = mozilla::MakeUnique<TestState>(); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + state->condition.wait(lock, [&state]() { return state->flag; }); + } + state->join(); + + CHECK(state->flag); + + return true; +} +END_TEST(testThreadingConditionVariablePredicate) + +BEGIN_TEST(testThreadingConditionVariableUntilOkay) { + auto state = mozilla::MakeUnique<TestState>(); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + while (!state->flag) { + auto to = + mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromSeconds(600); + js::CVStatus res = state->condition.wait_until(lock, to); + CHECK(res == js::CVStatus::NoTimeout); + } + } + state->join(); + + CHECK(state->flag); + + return true; +} +END_TEST(testThreadingConditionVariableUntilOkay) + +BEGIN_TEST(testThreadingConditionVariableUntilTimeout) { + auto state = mozilla::MakeUnique<TestState>(false); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + while (!state->flag) { + auto to = mozilla::TimeStamp::Now() + + mozilla::TimeDuration::FromMilliseconds(10); + js::CVStatus res = state->condition.wait_until(lock, to); + if (res == js::CVStatus::Timeout) { + break; + } + } + } + CHECK(!state->flag); + + // Timeout in the past should return with timeout immediately. + { + js::UniqueLock<js::Mutex> lock(state->mutex); + auto to = + mozilla::TimeStamp::Now() - mozilla::TimeDuration::FromMilliseconds(10); + js::CVStatus res = state->condition.wait_until(lock, to); + CHECK(res == js::CVStatus::Timeout); + } + + return true; +} +END_TEST(testThreadingConditionVariableUntilTimeout) + +BEGIN_TEST(testThreadingConditionVariableUntilOkayPredicate) { + auto state = mozilla::MakeUnique<TestState>(); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + auto to = + mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromSeconds(600); + bool res = state->condition.wait_until(lock, to, + [&state]() { return state->flag; }); + CHECK(res); + } + state->join(); + + CHECK(state->flag); + + return true; +} +END_TEST(testThreadingConditionVariableUntilOkayPredicate) + +BEGIN_TEST(testThreadingConditionVariableUntilTimeoutPredicate) { + auto state = mozilla::MakeUnique<TestState>(false); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + auto to = + mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromMilliseconds(10); + bool res = state->condition.wait_until(lock, to, + [&state]() { return state->flag; }); + CHECK(!res); + } + CHECK(!state->flag); + + return true; +} +END_TEST(testThreadingConditionVariableUntilTimeoutPredicate) + +BEGIN_TEST(testThreadingConditionVariableForOkay) { + auto state = mozilla::MakeUnique<TestState>(); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + while (!state->flag) { + auto duration = mozilla::TimeDuration::FromSeconds(600); + js::CVStatus res = state->condition.wait_for(lock, duration); + CHECK(res == js::CVStatus::NoTimeout); + } + } + state->join(); + + CHECK(state->flag); + + return true; +} +END_TEST(testThreadingConditionVariableForOkay) + +BEGIN_TEST(testThreadingConditionVariableForTimeout) { + auto state = mozilla::MakeUnique<TestState>(false); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + while (!state->flag) { + auto duration = mozilla::TimeDuration::FromMilliseconds(10); + js::CVStatus res = state->condition.wait_for(lock, duration); + if (res == js::CVStatus::Timeout) { + break; + } + } + } + CHECK(!state->flag); + + // Timeout in the past should return with timeout immediately. + { + js::UniqueLock<js::Mutex> lock(state->mutex); + auto duration = mozilla::TimeDuration::FromMilliseconds(-10); + js::CVStatus res = state->condition.wait_for(lock, duration); + CHECK(res == js::CVStatus::Timeout); + } + + return true; +} +END_TEST(testThreadingConditionVariableForTimeout) + +BEGIN_TEST(testThreadingConditionVariableForOkayPredicate) { + auto state = mozilla::MakeUnique<TestState>(); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + auto duration = mozilla::TimeDuration::FromSeconds(600); + bool res = state->condition.wait_for(lock, duration, + [&state]() { return state->flag; }); + CHECK(res); + } + state->join(); + + CHECK(state->flag); + + return true; +} +END_TEST(testThreadingConditionVariableForOkayPredicate) + +BEGIN_TEST(testThreadingConditionVariableForTimeoutPredicate) { + auto state = mozilla::MakeUnique<TestState>(false); + { + js::UniqueLock<js::Mutex> lock(state->mutex); + auto duration = mozilla::TimeDuration::FromMilliseconds(10); + bool res = state->condition.wait_for(lock, duration, + [&state]() { return state->flag; }); + CHECK(!res); + } + CHECK(!state->flag); + + return true; +} +END_TEST(testThreadingConditionVariableForTimeoutPredicate) |