Bug 1269823 - Use TimeDuration to provide timeouts for CondVar; r=jandem

--HG--
extra : rebase_source : daa7d0e5bafe1f96df133d8932f81e7b9562112d
This commit is contained in:
Terrence Cole 2016-05-19 13:26:42 -07:00
parent 81c4a32138
commit b744dd94ab
6 changed files with 35 additions and 25 deletions

View File

@ -7,6 +7,8 @@
#ifndef jslock_h
#define jslock_h
#include "mozilla/TimeStamp.h"
#ifdef JS_POSIX_NSPR
#include "vm/PosixNSPR.h"
@ -20,4 +22,13 @@
#endif
inline PRIntervalTime
DurationToPRInterval(mozilla::TimeDuration duration)
{
double millis = duration.ToMilliseconds();
return millis < double(UINT32_MAX)
? PR_MillisecondsToInterval(millis)
: PR_INTERVAL_NO_TIMEOUT;
}
#endif /* jslock_h */

View File

@ -14,6 +14,7 @@
#include "mozilla/mozalloc.h"
#include "mozilla/PodOperations.h"
#include "mozilla/SizePrintfMacros.h"
#include "mozilla/TimeStamp.h"
#ifdef XP_WIN
# include <direct.h>
@ -107,6 +108,8 @@ using mozilla::Maybe;
using mozilla::NumberEqualsInt32;
using mozilla::PodCopy;
using mozilla::PodEqual;
using mozilla::TimeDuration;
using mozilla::TimeStamp;
enum JSShellExitCode {
EXITCODE_RUNTIME_ERROR = 3,
@ -131,7 +134,7 @@ static const size_t gMaxStackSize = 128 * sizeof(size_t) * 1024;
* Limit the timeout to 30 minutes to prevent an overflow on platfoms
* that represent the time internally in microseconds using 32-bit int.
*/
static const double MAX_TIMEOUT_INTERVAL = 1800.0;
static const double MAX_TIMEOUT_INTERVAL = 1800.0; // seconds
#ifdef NIGHTLY_BUILD
# define SHARED_MEMORY_DEFAULT 1
@ -3086,13 +3089,10 @@ Sleep_fn(JSContext* cx, unsigned argc, Value* vp)
{
ShellRuntime* sr = GetShellRuntime(cx);
CallArgs args = CallArgsFromVp(argc, vp);
int64_t t_ticks;
if (args.length() == 0) {
t_ticks = 0;
} else {
TimeDuration duration = TimeDuration::FromSeconds(0.0);
if (args.length() > 0) {
double t_secs;
if (!ToNumber(cx, args[0], &t_secs))
return false;
@ -3101,20 +3101,18 @@ Sleep_fn(JSContext* cx, unsigned argc, Value* vp)
JS_ReportError(cx, "Excessive sleep interval");
return false;
}
t_ticks = (t_secs <= 0.0)
? 0
: int64_t(PRMJ_USEC_PER_SEC * t_secs);
duration = TimeDuration::FromSeconds(Max(0.0, t_secs));
}
PR_Lock(sr->watchdogLock);
int64_t to_wakeup = PRMJ_Now() + t_ticks;
TimeStamp toWakeup = TimeStamp::Now() + duration;
for (;;) {
PR_WaitCondVar(sr->sleepWakeup, PR_MillisecondsToInterval(t_ticks / 1000));
PR_WaitCondVar(sr->sleepWakeup, DurationToPRInterval(duration));
if (sr->serviceInterrupt)
break;
int64_t now = PRMJ_Now();
if (!IsBefore(now, to_wakeup))
auto now = TimeStamp::Now();
if (now >= toWakeup)
break;
t_ticks = to_wakeup - now;
duration = toWakeup - now;
}
PR_Unlock(sr->watchdogLock);
args.rval().setUndefined();
@ -3196,11 +3194,11 @@ WatchdogMain(void* arg)
JS_RequestInterruptCallback(rt);
}
uint64_t sleepDuration = PR_INTERVAL_NO_TIMEOUT;
if (sr->watchdogHasTimeout)
sleepDuration = PR_TicksPerSecond() / 10;
TimeDuration sleepDuration = sr->watchdogHasTimeout
? TimeDuration::FromSeconds(0.1)
: TimeDuration::Forever();
mozilla::DebugOnly<PRStatus> status =
PR_WaitCondVar(sr->watchdogWakeup, sleepDuration);
PR_WaitCondVar(sr->watchdogWakeup, DurationToPRInterval(sleepDuration));
MOZ_ASSERT(status == PR_SUCCESS);
}
}

View File

@ -29,6 +29,7 @@ using namespace js;
using mozilla::ArrayLength;
using mozilla::DebugOnly;
using mozilla::TimeDuration;
namespace js {
@ -704,15 +705,13 @@ GlobalHelperThreadState::isLocked()
#endif
void
GlobalHelperThreadState::wait(CondVar which, uint32_t millis)
GlobalHelperThreadState::wait(CondVar which, TimeDuration timeout /* = TimeDuration::Forever() */)
{
MOZ_ASSERT(isLocked());
#ifdef DEBUG
lockOwner = nullptr;
#endif
DebugOnly<PRStatus> status =
PR_WaitCondVar(whichWakeup(which),
millis ? PR_MillisecondsToInterval(millis) : PR_INTERVAL_NO_TIMEOUT);
DebugOnly<PRStatus> status = PR_WaitCondVar(whichWakeup(which), DurationToPRInterval(timeout));
MOZ_ASSERT(status == PR_SUCCESS);
#ifdef DEBUG
lockOwner = PR_GetCurrentThread();

View File

@ -15,6 +15,7 @@
#include "mozilla/GuardObjects.h"
#include "mozilla/PodOperations.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Variant.h"
#include "jscntxt.h"
@ -132,7 +133,7 @@ class GlobalHelperThreadState
PAUSE
};
void wait(CondVar which, uint32_t timeoutMillis = 0);
void wait(CondVar which, mozilla::TimeDuration timeout = mozilla::TimeDuration::Forever());
void notifyAll(CondVar which);
void notifyOne(CondVar which);

View File

@ -343,7 +343,7 @@ PR_TicksPerSecond()
}
PRStatus
PR_WaitCondVar(PRCondVar* cvar, uint32_t timeout)
PR_WaitCondVar(PRCondVar* cvar, PRIntervalTime timeout)
{
if (timeout == PR_INTERVAL_NO_TIMEOUT) {
if (pthread_cond_wait(&cvar->cond(), &cvar->lock()->mutex()))

View File

@ -21,6 +21,7 @@ class CondVar;
typedef nspr::Thread PRThread;
typedef nspr::Lock PRLock;
typedef nspr::CondVar PRCondVar;
using PRIntervalTime = uint32_t;
enum PRThreadType {
PR_USER_THREAD,
@ -135,7 +136,7 @@ uint32_t
PR_TicksPerSecond();
PRStatus
PR_WaitCondVar(PRCondVar* cvar, uint32_t timeout);
PR_WaitCondVar(PRCondVar* cvar, PRIntervalTime timeout);
#endif /* JS_POSIX_NSPR */