summaryrefslogtreecommitdiffstats
path: root/js/src/jsapi-tests/testThreadingConditionVariable.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jsapi-tests/testThreadingConditionVariable.cpp')
-rw-r--r--js/src/jsapi-tests/testThreadingConditionVariable.cpp220
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)