Bug 1275306 - Part 2: Use a TimeStamp to implement watchdogTimeout; r=jandem

--HG--
extra : rebase_source : 541667d40097487d5b07b687f7c3ef105c18109b
This commit is contained in:
Terrence Cole 2016-05-25 09:39:57 -07:00
Родитель c78f0cf856
Коммит bca258388c
1 изменённых файлов: 13 добавлений и 27 удалений

Просмотреть файл

@ -105,6 +105,7 @@ using namespace js::shell;
using mozilla::ArrayLength;
using mozilla::Atomic;
using mozilla::Maybe;
using mozilla::Nothing;
using mozilla::NumberEqualsInt32;
using mozilla::PodCopy;
using mozilla::PodEqual;
@ -169,8 +170,7 @@ struct ShellRuntime
PRLock* watchdogLock;
PRCondVar* watchdogWakeup;
PRThread* watchdogThread;
bool watchdogHasTimeout;
int64_t watchdogTimeout;
Maybe<TimeStamp> watchdogTimeout;
PRCondVar* sleepWakeup;
@ -318,8 +318,6 @@ ShellRuntime::ShellRuntime(JSRuntime* rt)
watchdogLock(nullptr),
watchdogWakeup(nullptr),
watchdogThread(nullptr),
watchdogHasTimeout(false),
watchdogTimeout(0),
sleepWakeup(nullptr),
exitCode(0),
quitting(false),
@ -3084,17 +3082,6 @@ ShapeOf(JSContext* cx, unsigned argc, JS::Value* vp)
return true;
}
/*
* Check that t1 comes strictly before t2. The function correctly deals with
* wrap-around between t2 and t1 assuming that t2 and t1 stays within INT32_MAX
* from each other. We use MAX_TIMEOUT_INTERVAL to enforce this restriction.
*/
static bool
IsBefore(int64_t t1, int64_t t2)
{
return int32_t(t1 - t2) < 0;
}
static bool
Sleep_fn(JSContext* cx, unsigned argc, Value* vp)
{
@ -3183,13 +3170,13 @@ WatchdogMain(void* arg)
PR_Lock(sr->watchdogLock);
while (sr->watchdogThread) {
int64_t now = PRMJ_Now();
if (sr->watchdogHasTimeout && !IsBefore(now, sr->watchdogTimeout)) {
auto now = TimeStamp::Now();
if (sr->watchdogTimeout.isSome() && now >= sr->watchdogTimeout.value()) {
/*
* The timeout has just expired. Request an interrupt callback
* outside the lock.
*/
sr->watchdogHasTimeout = false;
sr->watchdogTimeout = Nothing();
PR_Unlock(sr->watchdogLock);
CancelExecution(rt);
PR_Lock(sr->watchdogLock);
@ -3197,7 +3184,7 @@ WatchdogMain(void* arg)
/* Wake up any threads doing sleep. */
PR_NotifyAllCondVar(sr->sleepWakeup);
} else {
if (sr->watchdogHasTimeout) {
if (sr->watchdogTimeout.isSome()) {
/*
* Time hasn't expired yet. Simulate an interrupt callback
* which doesn't abort execution.
@ -3205,7 +3192,7 @@ WatchdogMain(void* arg)
JS_RequestInterruptCallback(rt);
}
TimeDuration sleepDuration = sr->watchdogHasTimeout
TimeDuration sleepDuration = sr->watchdogTimeout.isSome()
? TimeDuration::FromSeconds(0.1)
: TimeDuration::Forever();
mozilla::DebugOnly<PRStatus> status =
@ -3223,16 +3210,16 @@ ScheduleWatchdog(JSRuntime* rt, double t)
if (t <= 0) {
PR_Lock(sr->watchdogLock);
sr->watchdogHasTimeout = false;
sr->watchdogTimeout = Nothing();
PR_Unlock(sr->watchdogLock);
return true;
}
int64_t interval = int64_t(ceil(t * PRMJ_USEC_PER_SEC));
int64_t timeout = PRMJ_Now() + interval;
auto interval = TimeDuration::FromSeconds(t);
auto timeout = TimeStamp::Now() + interval;
PR_Lock(sr->watchdogLock);
if (!sr->watchdogThread) {
MOZ_ASSERT(!sr->watchdogHasTimeout);
MOZ_ASSERT(sr->watchdogTimeout.isNothing());
sr->watchdogThread = PR_CreateThread(PR_USER_THREAD,
WatchdogMain,
rt,
@ -3244,11 +3231,10 @@ ScheduleWatchdog(JSRuntime* rt, double t)
PR_Unlock(sr->watchdogLock);
return false;
}
} else if (!sr->watchdogHasTimeout || IsBefore(timeout, sr->watchdogTimeout)) {
} else if (sr->watchdogTimeout.isNothing() || timeout < sr->watchdogTimeout.value()) {
PR_NotifyCondVar(sr->watchdogWakeup);
}
sr->watchdogHasTimeout = true;
sr->watchdogTimeout = timeout;
sr->watchdogTimeout = Some(timeout);
PR_Unlock(sr->watchdogLock);
return true;
}