From 166e149908e14e9cfede1f617eae226711091058 Mon Sep 17 00:00:00 2001 From: Sebastian Hengst Date: Sat, 28 May 2016 01:39:00 +0200 Subject: [PATCH] Backed out changeset 67d13c5fcf84 (bug 956899) --- js/src/shell/js.cpp | 118 +++++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 40 deletions(-) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index dddb1cf821fe..1499358daba6 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -79,9 +79,6 @@ #include "shell/jsoptparse.h" #include "shell/jsshell.h" #include "shell/OSObject.h" -#include "threading/ConditionVariable.h" -#include "threading/LockGuard.h" -#include "threading/Mutex.h" #include "vm/ArgumentsObject.h" #include "vm/Compression.h" #include "vm/Debugger.h" @@ -170,12 +167,12 @@ struct ShellRuntime /* * Watchdog thread state. */ - Mutex watchdogLock; - ConditionVariable watchdogWakeup; + PRLock* watchdogLock; + PRCondVar* watchdogWakeup; PRThread* watchdogThread; Maybe watchdogTimeout; - ConditionVariable sleepWakeup; + PRCondVar* sleepWakeup; int exitCode; bool quitting; @@ -219,6 +216,9 @@ mozilla::Atomic jsCacheOpened(false); static bool SetTimeoutValue(JSContext* cx, double t); +static bool +InitWatchdog(JSRuntime* rt); + static void KillWatchdog(JSRuntime *rt); @@ -315,7 +315,10 @@ ShellRuntime::ShellRuntime(JSRuntime* rt) #ifdef SPIDERMONKEY_PROMISE promiseRejectionTrackerCallback(rt, NullValue()), #endif // SPIDERMONKEY_PROMISE + watchdogLock(nullptr), + watchdogWakeup(nullptr), watchdogThread(nullptr), + sleepWakeup(nullptr), exitCode(0), quitting(false), gotError(false) @@ -2933,6 +2936,12 @@ WorkerMain(void* arg) JS_InitDestroyPrincipalsCallback(rt, ShellPrincipals::destroy); SetWorkerRuntimeOptions(rt); + if (!InitWatchdog(rt)) { + JS_DestroyRuntime(rt); + js_delete(input); + return; + } + JSContext* cx = NewContext(rt); if (!cx) { JS_DestroyRuntime(rt); @@ -3092,43 +3101,63 @@ Sleep_fn(JSContext* cx, unsigned argc, Value* vp) return false; } } - { - LockGuard guard(sr->watchdogLock); - TimeStamp toWakeup = TimeStamp::Now() + duration; - for (;;) { - sr->sleepWakeup.wait_for(guard, duration); - if (sr->serviceInterrupt) - break; - auto now = TimeStamp::Now(); - if (now >= toWakeup) - break; - duration = toWakeup - now; - } + PR_Lock(sr->watchdogLock); + TimeStamp toWakeup = TimeStamp::Now() + duration; + for (;;) { + PR_WaitCondVar(sr->sleepWakeup, DurationToPRInterval(duration)); + if (sr->serviceInterrupt) + break; + auto now = TimeStamp::Now(); + if (now >= toWakeup) + break; + duration = toWakeup - now; } + PR_Unlock(sr->watchdogLock); args.rval().setUndefined(); return !sr->serviceInterrupt; } +static bool +InitWatchdog(JSRuntime* rt) +{ + ShellRuntime* sr = GetShellRuntime(rt); + MOZ_ASSERT(!sr->watchdogThread); + sr->watchdogLock = PR_NewLock(); + if (sr->watchdogLock) { + sr->watchdogWakeup = PR_NewCondVar(sr->watchdogLock); + if (sr->watchdogWakeup) { + sr->sleepWakeup = PR_NewCondVar(sr->watchdogLock); + if (sr->sleepWakeup) + return true; + PR_DestroyCondVar(sr->watchdogWakeup); + } + PR_DestroyLock(sr->watchdogLock); + } + return false; +} + static void KillWatchdog(JSRuntime* rt) { ShellRuntime* sr = GetShellRuntime(rt); PRThread* thread; - { - LockGuard guard(sr->watchdogLock); - thread = sr->watchdogThread; - if (thread) { - /* - * The watchdog thread is running, tell it to terminate waking it up - * if necessary. - */ - sr->watchdogThread = nullptr; - sr->watchdogWakeup.notify_one(); - } + PR_Lock(sr->watchdogLock); + thread = sr->watchdogThread; + if (thread) { + /* + * The watchdog thread is running, tell it to terminate waking it up + * if necessary. + */ + sr->watchdogThread = nullptr; + PR_NotifyCondVar(sr->watchdogWakeup); } + PR_Unlock(sr->watchdogLock); if (thread) PR_JoinThread(thread); + PR_DestroyCondVar(sr->sleepWakeup); + PR_DestroyCondVar(sr->watchdogWakeup); + PR_DestroyLock(sr->watchdogLock); } static void @@ -3139,7 +3168,7 @@ WatchdogMain(void* arg) JSRuntime* rt = (JSRuntime*) arg; ShellRuntime* sr = GetShellRuntime(rt); - LockGuard guard(sr->watchdogLock); + PR_Lock(sr->watchdogLock); while (sr->watchdogThread) { auto now = TimeStamp::Now(); if (sr->watchdogTimeout.isSome() && now >= sr->watchdogTimeout.value()) { @@ -3148,13 +3177,12 @@ WatchdogMain(void* arg) * outside the lock. */ sr->watchdogTimeout = Nothing(); - { - UnlockGuard unlock(guard); - CancelExecution(rt); - } + PR_Unlock(sr->watchdogLock); + CancelExecution(rt); + PR_Lock(sr->watchdogLock); /* Wake up any threads doing sleep. */ - sr->sleepWakeup.notify_all(); + PR_NotifyAllCondVar(sr->sleepWakeup); } else { if (sr->watchdogTimeout.isSome()) { /* @@ -3167,9 +3195,12 @@ WatchdogMain(void* arg) TimeDuration sleepDuration = sr->watchdogTimeout.isSome() ? TimeDuration::FromSeconds(0.1) : TimeDuration::Forever(); - sr->watchdogWakeup.wait_for(guard, sleepDuration); + mozilla::DebugOnly status = + PR_WaitCondVar(sr->watchdogWakeup, DurationToPRInterval(sleepDuration)); + MOZ_ASSERT(status == PR_SUCCESS); } } + PR_Unlock(sr->watchdogLock); } static bool @@ -3178,14 +3209,15 @@ ScheduleWatchdog(JSRuntime* rt, double t) ShellRuntime* sr = GetShellRuntime(rt); if (t <= 0) { - LockGuard guard(sr->watchdogLock); + PR_Lock(sr->watchdogLock); sr->watchdogTimeout = Nothing(); + PR_Unlock(sr->watchdogLock); return true; } auto interval = TimeDuration::FromSeconds(t); auto timeout = TimeStamp::Now() + interval; - LockGuard guard(sr->watchdogLock); + PR_Lock(sr->watchdogLock); if (!sr->watchdogThread) { MOZ_ASSERT(sr->watchdogTimeout.isNothing()); sr->watchdogThread = PR_CreateThread(PR_USER_THREAD, @@ -3195,12 +3227,15 @@ ScheduleWatchdog(JSRuntime* rt, double t) PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - if (!sr->watchdogThread) + if (!sr->watchdogThread) { + PR_Unlock(sr->watchdogLock); return false; + } } else if (sr->watchdogTimeout.isNothing() || timeout < sr->watchdogTimeout.value()) { - sr->watchdogWakeup.notify_one(); + PR_NotifyCondVar(sr->watchdogWakeup); } sr->watchdogTimeout = Some(timeout); + PR_Unlock(sr->watchdogLock); return true; } @@ -7395,6 +7430,9 @@ main(int argc, char** argv, char** envp) if (!offThreadState.init()) return 1; + if (!InitWatchdog(rt)) + return 1; + cx = NewContext(rt); if (!cx) return 1;