mirror of
https://github.com/denoland/deno.git
synced 2025-01-05 13:59:01 -05:00
Fix clearTimer bug (#3143)
This commit is contained in:
parent
c876d1adb4
commit
4ae1838a6e
2 changed files with 17 additions and 2 deletions
|
@ -44,16 +44,19 @@ function clearGlobalTimeout(): void {
|
||||||
sendSync(dispatch.OP_GLOBAL_TIMER_STOP);
|
sendSync(dispatch.OP_GLOBAL_TIMER_STOP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pendingEvents = 0;
|
||||||
|
|
||||||
async function setGlobalTimeout(due: number, now: number): Promise<void> {
|
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
|
// 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
|
// relative time value. On the Rust side we'll turn that into an absolute
|
||||||
// value again.
|
// value again.
|
||||||
const timeout = due - now;
|
const timeout = due - now;
|
||||||
assert(timeout >= 0);
|
assert(timeout >= 0);
|
||||||
|
|
||||||
// Send message to the backend.
|
// Send message to the backend.
|
||||||
globalTimeoutDue = due;
|
globalTimeoutDue = due;
|
||||||
|
pendingEvents++;
|
||||||
await sendAsync(dispatch.OP_GLOBAL_TIMER, { timeout });
|
await sendAsync(dispatch.OP_GLOBAL_TIMER, { timeout });
|
||||||
|
pendingEvents--;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||||
fireTimers();
|
fireTimers();
|
||||||
}
|
}
|
||||||
|
@ -139,7 +142,7 @@ function fire(timer: Timer): void {
|
||||||
function fireTimers(): void {
|
function fireTimers(): void {
|
||||||
const now = getTime();
|
const now = getTime();
|
||||||
// Bail out if we're not expecting the global timer to fire.
|
// Bail out if we're not expecting the global timer to fire.
|
||||||
if (globalTimeoutDue === null) {
|
if (globalTimeoutDue === null || pendingEvents > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// After firing the timers that are due now, this will hold the due time of
|
// After firing the timers that are due now, this will hold the due time of
|
||||||
|
|
|
@ -289,3 +289,15 @@ test(function testFunctionParamsLength(): void {
|
||||||
test(function clearTimeoutAndClearIntervalNotBeEquals(): void {
|
test(function clearTimeoutAndClearIntervalNotBeEquals(): void {
|
||||||
assertNotEquals(clearTimeout, clearInterval);
|
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);
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue