Bug 956899 - Use js::Thread for JS shell watchdog thread; r=jandem

This commit is contained in:
Terrence Cole 2016-05-28 16:10:15 +02:00
parent 84f84eff04
commit 9aa799a990

View File

@ -82,6 +82,7 @@
#include "threading/ConditionVariable.h" #include "threading/ConditionVariable.h"
#include "threading/LockGuard.h" #include "threading/LockGuard.h"
#include "threading/Mutex.h" #include "threading/Mutex.h"
#include "threading/Thread.h"
#include "vm/ArgumentsObject.h" #include "vm/ArgumentsObject.h"
#include "vm/Compression.h" #include "vm/Compression.h"
#include "vm/Debugger.h" #include "vm/Debugger.h"
@ -172,7 +173,7 @@ struct ShellRuntime
*/ */
Mutex watchdogLock; Mutex watchdogLock;
ConditionVariable watchdogWakeup; ConditionVariable watchdogWakeup;
PRThread* watchdogThread; Maybe<Thread> watchdogThread;
Maybe<TimeStamp> watchdogTimeout; Maybe<TimeStamp> watchdogTimeout;
ConditionVariable sleepWakeup; ConditionVariable sleepWakeup;
@ -324,7 +325,6 @@ ShellRuntime::ShellRuntime(JSRuntime* rt)
#ifdef SPIDERMONKEY_PROMISE #ifdef SPIDERMONKEY_PROMISE
promiseRejectionTrackerCallback(rt, NullValue()), promiseRejectionTrackerCallback(rt, NullValue()),
#endif // SPIDERMONKEY_PROMISE #endif // SPIDERMONKEY_PROMISE
watchdogThread(nullptr),
exitCode(0), exitCode(0),
quitting(false) quitting(false)
{} {}
@ -3133,36 +3133,33 @@ static void
KillWatchdog(JSRuntime* rt) KillWatchdog(JSRuntime* rt)
{ {
ShellRuntime* sr = GetShellRuntime(rt); ShellRuntime* sr = GetShellRuntime(rt);
PRThread* thread; Maybe<Thread> thread;
{ {
LockGuard<Mutex> guard(sr->watchdogLock); LockGuard<Mutex> guard(sr->watchdogLock);
thread = sr->watchdogThread; Swap(sr->watchdogThread, thread);
if (thread) { if (thread) {
/* // The watchdog thread becoming Nothing is its signal to exit.
* The watchdog thread is running, tell it to terminate waking it up
* if necessary.
*/
sr->watchdogThread = nullptr;
sr->watchdogWakeup.notify_one(); sr->watchdogWakeup.notify_one();
} }
} }
if (thread) if (thread)
PR_JoinThread(thread); thread->join();
MOZ_ASSERT(!sr->watchdogThread);
} }
static void static void
WatchdogMain(void* arg) WatchdogMain(JSRuntime* rt)
{ {
PR_SetCurrentThreadName("JS Watchdog"); ThisThread::SetName("JS Watchdog");
JSRuntime* rt = (JSRuntime*) arg;
ShellRuntime* sr = GetShellRuntime(rt); ShellRuntime* sr = GetShellRuntime(rt);
LockGuard<Mutex> guard(sr->watchdogLock); LockGuard<Mutex> guard(sr->watchdogLock);
while (sr->watchdogThread) { while (sr->watchdogThread) {
auto now = TimeStamp::Now(); auto now = TimeStamp::Now();
if (sr->watchdogTimeout.isSome() && now >= sr->watchdogTimeout.value()) { if (sr->watchdogTimeout && now >= sr->watchdogTimeout.value()) {
/* /*
* The timeout has just expired. Request an interrupt callback * The timeout has just expired. Request an interrupt callback
* outside the lock. * outside the lock.
@ -3176,7 +3173,7 @@ WatchdogMain(void* arg)
/* Wake up any threads doing sleep. */ /* Wake up any threads doing sleep. */
sr->sleepWakeup.notify_all(); sr->sleepWakeup.notify_all();
} else { } else {
if (sr->watchdogTimeout.isSome()) { if (sr->watchdogTimeout) {
/* /*
* Time hasn't expired yet. Simulate an interrupt callback * Time hasn't expired yet. Simulate an interrupt callback
* which doesn't abort execution. * which doesn't abort execution.
@ -3184,7 +3181,7 @@ WatchdogMain(void* arg)
JS_RequestInterruptCallback(rt); JS_RequestInterruptCallback(rt);
} }
TimeDuration sleepDuration = sr->watchdogTimeout.isSome() TimeDuration sleepDuration = sr->watchdogTimeout
? TimeDuration::FromSeconds(0.1) ? TimeDuration::FromSeconds(0.1)
: TimeDuration::Forever(); : TimeDuration::Forever();
sr->watchdogWakeup.wait_for(guard, sleepDuration); sr->watchdogWakeup.wait_for(guard, sleepDuration);
@ -3207,17 +3204,9 @@ ScheduleWatchdog(JSRuntime* rt, double t)
auto timeout = TimeStamp::Now() + interval; auto timeout = TimeStamp::Now() + interval;
LockGuard<Mutex> guard(sr->watchdogLock); LockGuard<Mutex> guard(sr->watchdogLock);
if (!sr->watchdogThread) { if (!sr->watchdogThread) {
MOZ_ASSERT(sr->watchdogTimeout.isNothing()); MOZ_ASSERT(!sr->watchdogTimeout);
sr->watchdogThread = PR_CreateThread(PR_USER_THREAD, sr->watchdogThread.emplace(WatchdogMain, rt);
WatchdogMain, } else if (!sr->watchdogTimeout || timeout < sr->watchdogTimeout.value()) {
rt,
PR_PRIORITY_NORMAL,
PR_GLOBAL_THREAD,
PR_JOINABLE_THREAD,
0);
if (!sr->watchdogThread)
return false;
} else if (sr->watchdogTimeout.isNothing() || timeout < sr->watchdogTimeout.value()) {
sr->watchdogWakeup.notify_one(); sr->watchdogWakeup.notify_one();
} }
sr->watchdogTimeout = Some(timeout); sr->watchdogTimeout = Some(timeout);