0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-29 08:58:01 -04:00

Fix clearTimer bug (#3143)

This commit is contained in:
Ry Dahl 2019-10-19 17:09:24 -04:00 committed by GitHub
parent c876d1adb4
commit 4ae1838a6e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 2 deletions

View file

@ -44,16 +44,19 @@ function clearGlobalTimeout(): void {
sendSync(dispatch.OP_GLOBAL_TIMER_STOP);
}
let pendingEvents = 0;
async function setGlobalTimeout(due: number, now: number): Promise<void> {
// Since JS and Rust don't use the same clock, pass the time to rust as a
// relative time value. On the Rust side we'll turn that into an absolute
// value again.
const timeout = due - now;
assert(timeout >= 0);
// Send message to the backend.
globalTimeoutDue = due;
pendingEvents++;
await sendAsync(dispatch.OP_GLOBAL_TIMER, { timeout });
pendingEvents--;
// eslint-disable-next-line @typescript-eslint/no-use-before-define
fireTimers();
}
@ -139,7 +142,7 @@ function fire(timer: Timer): void {
function fireTimers(): void {
const now = getTime();
// Bail out if we're not expecting the global timer to fire.
if (globalTimeoutDue === null) {
if (globalTimeoutDue === null || pendingEvents > 0) {
return;
}
// After firing the timers that are due now, this will hold the due time of

View file

@ -289,3 +289,15 @@ test(function testFunctionParamsLength(): void {
test(function clearTimeoutAndClearIntervalNotBeEquals(): void {
assertNotEquals(clearTimeout, clearInterval);
});
test(async function timerMaxCpuBug(): Promise<void> {
// There was a bug where clearing a timeout would cause Deno to use 100% CPU.
clearTimeout(setTimeout(() => {}, 1000));
// We can check this by counting how many ops have triggered in the interim.
// Certainly less than 10 ops should have been dispatched in next 100 ms.
const { opsDispatched } = Deno.metrics();
await waitForMs(100);
const opsDispatched_ = Deno.metrics().opsDispatched;
console.log("opsDispatched", opsDispatched, "opsDispatched_", opsDispatched_);
assert(opsDispatched_ - opsDispatched < 10);
});