Bug 1253351 - count argument of futexWake defaults to +Infinity. r=bbouvier

--HG--
extra : rebase_source : 269248db8d70f6e5c55836129b50fba621c3e7f7
This commit is contained in:
Lars T Hansen 2016-03-24 17:01:26 +01:00
Родитель b40b83ba87
Коммит 43a06b20d4
2 изменённых файлов: 52 добавлений и 20 удалений

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

@ -852,10 +852,14 @@ js::atomics_futexWake(JSContext* cx, unsigned argc, Value* vp)
if (!GetTypedArrayIndex(cx, idxv, view, &offset)) if (!GetTypedArrayIndex(cx, idxv, view, &offset))
return false; return false;
double count; double count;
if (!ToInteger(cx, countv, &count)) if (countv.isUndefined()) {
return false; count = mozilla::PositiveInfinity<double>();
if (count < 0) } else {
count = 0; if (!ToInteger(cx, countv, &count))
return false;
if (count < 0.0)
count = 0.0;
}
AutoLockFutexAPI lock; AutoLockFutexAPI lock;
@ -901,10 +905,14 @@ js::atomics_futexWakeOrRequeue(JSContext* cx, unsigned argc, Value* vp)
if (!GetTypedArrayIndex(cx, idx1v, view, &offset1)) if (!GetTypedArrayIndex(cx, idx1v, view, &offset1))
return false; return false;
double count; double count;
if (!ToInteger(cx, countv, &count)) if (countv.isUndefined()) {
return false; count = mozilla::PositiveInfinity<double>();
if (count < 0) } else {
count = 0; if (!ToInteger(cx, countv, &count))
return false;
if (count < 0.0)
count = 0.0;
}
int32_t value; int32_t value;
if (!ToInt32(cx, valv, &value)) if (!ToInt32(cx, valv, &value))
return false; return false;

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

@ -61,19 +61,22 @@ assertThrowsInstanceOf(() => setSharedArrayBuffer(() => 37), Error);
// Futex test // Futex test
if (helperThreadCount() === 0) {
// Abort if there is no helper thread.
reportCompare(true,true);
quit();
}
////////////////////////////////////////////////////////////
// Main is sharing the buffer with the worker; the worker is clearing // Main is sharing the buffer with the worker; the worker is clearing
// the buffer. // the buffer.
mem[0] = 42; mem[0] = 42;
mem[1] = 37; mem[1] = 37;
mem[2] = DEBUG; mem[2] = DEBUG;
setSharedArrayBuffer(mem.buffer);
if (helperThreadCount() === 0) { setSharedArrayBuffer(mem.buffer);
// Abort if there is no helper thread.
reportCompare(true,true);
quit();
}
evalInWorker(` evalInWorker(`
var mem = new Int32Array(getSharedArrayBuffer()); var mem = new Int32Array(getSharedArrayBuffer());
@ -83,11 +86,11 @@ function dprint(s) {
assertEq(mem[0], 42); // what was written in the main thread assertEq(mem[0], 42); // what was written in the main thread
assertEq(mem[1], 37); // is read in the worker assertEq(mem[1], 37); // is read in the worker
mem[1] = 1337; mem[1] = 1337;
dprint("Sleeping for 3 seconds"); dprint("Sleeping for 2 seconds");
sleep(3); sleep(2);
dprint("Waking the main thread now"); dprint("Waking the main thread now");
setSharedArrayBuffer(null); setSharedArrayBuffer(null);
Atomics.futexWake(mem, 0, 1); assertEq(Atomics.futexWake(mem, 0, 1), 1); // Can fail spuriously but very unlikely
`); `);
var then = Date.now(); var then = Date.now();
@ -96,12 +99,31 @@ dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
assertEq(mem[1], 1337); // what was written in the worker is read in the main thread assertEq(mem[1], 1337); // what was written in the worker is read in the main thread
assertEq(getSharedArrayBuffer(), null); // The worker's clearing of the mbx is visible assertEq(getSharedArrayBuffer(), null); // The worker's clearing of the mbx is visible
////////////////////////////////////////////////////////////
// Test the default argument to futexWake()
setSharedArrayBuffer(mem.buffer);
evalInWorker(`
var mem = new Int32Array(getSharedArrayBuffer());
sleep(2); // Probably long enough to avoid a spurious error next
assertEq(Atomics.futexWake(mem, 0), 1); // Last argument to futexWake should default to +Infinity
`);
var then = Date.now();
dprint("Main thread waiting on wakeup (2s)");
assertEq(Atomics.futexWait(mem, 0, 42), Atomics.OK);
dprint("Woke up as I should have in " + (Date.now() - then)/1000 + "s");
////////////////////////////////////////////////////////////
// A tricky case: while in the wait there will be an interrupt, and in // A tricky case: while in the wait there will be an interrupt, and in
// the interrupt handler we will execute a futexWait. This is // the interrupt handler we will execute a futexWait. This is
// explicitly prohibited (for now), so there should be a catchable exception. // explicitly prohibited (for now), so there should be a catchable exception.
timeout(2, function () { timeout(2, function () {
dprint("In the interrupt, starting inner wait"); dprint("In the interrupt, starting inner wait with timeout 2s");
Atomics.futexWait(mem, 0, 42); // Should throw and propagate all the way out Atomics.futexWait(mem, 0, 42); // Should throw and propagate all the way out
}); });
var exn = false; var exn = false;
@ -110,13 +132,15 @@ try {
assertEq(Atomics.futexWait(mem, 0, 42, 5000), Atomics.OK); assertEq(Atomics.futexWait(mem, 0, 42, 5000), Atomics.OK);
} }
catch (e) { catch (e) {
dprint("Got the exception!"); dprint("Got the timeout exception!");
exn = true; exn = true;
} }
finally { finally {
timeout(-1); timeout(-1);
} }
assertEq(exn, true); assertEq(exn, true);
dprint("Done");
////////////////////////////////////////////////////////////
dprint("Done");
reportCompare(true,true); reportCompare(true,true);