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