Skip to content

Commit 1385e1b

Browse files
zhangzifaBridgeAR
authored andcommitted
timers: setInterval interval includes cb duration
setInterval callback should be scheduled on the interval Fixes: #7346 PR-URL: #14815 Fixes: #7346 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
1 parent e8c491a commit 1385e1b

File tree

2 files changed

+36
-5
lines changed

2 files changed

+36
-5
lines changed

lib/timers.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,11 +167,15 @@ exports._unrefActive = function(item) {
167167
// Appends a timer onto the end of an existing timers list, or creates a new
168168
// TimerWrap backed list if one does not already exist for the specified timeout
169169
// duration.
170-
function insert(item, unrefed) {
170+
function insert(item, unrefed, start) {
171171
const msecs = item._idleTimeout;
172172
if (msecs < 0 || msecs === undefined) return;
173173

174-
item._idleStart = TimerWrap.now();
174+
if (typeof start === 'number') {
175+
item._idleStart = start;
176+
} else {
177+
item._idleStart = TimerWrap.now();
178+
}
175179

176180
const lists = unrefed === true ? unrefedLists : refedLists;
177181

@@ -446,16 +450,17 @@ function ontimeout(timer) {
446450
var args = timer._timerArgs;
447451
if (typeof timer._onTimeout !== 'function')
448452
return promiseResolve(timer._onTimeout, args[0]);
453+
const start = TimerWrap.now();
449454
if (!args)
450455
timer._onTimeout();
451456
else
452457
Reflect.apply(timer._onTimeout, timer, args);
453458
if (timer._repeat)
454-
rearm(timer);
459+
rearm(timer, start);
455460
}
456461

457462

458-
function rearm(timer) {
463+
function rearm(timer, start) {
459464
// // Do not re-arm unenroll'd or closed timers.
460465
if (timer._idleTimeout === -1) return;
461466

@@ -464,7 +469,15 @@ function rearm(timer) {
464469
timer._handle.start(timer._repeat);
465470
} else {
466471
timer._idleTimeout = timer._repeat;
467-
active(timer);
472+
473+
const duration = TimerWrap.now() - start;
474+
if (duration >= timer._repeat) {
475+
// If callback duration >= timer._repeat,
476+
// add 1 ms to avoid blocking eventloop
477+
insert(timer, false, start + duration - timer._repeat + 1);
478+
} else {
479+
insert(timer, false, start);
480+
}
468481
}
469482
}
470483

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
'use strict';
2+
const common = require('../common');
3+
const Timer = process.binding('timer_wrap').Timer;
4+
const assert = require('assert');
5+
6+
let cntr = 0;
7+
let first, second;
8+
const t = setInterval(() => {
9+
common.busyLoop(50);
10+
cntr++;
11+
if (cntr === 1) {
12+
first = Timer.now();
13+
} else if (cntr === 2) {
14+
second = Timer.now();
15+
assert(Math.abs(second - first - 100) < 10);
16+
clearInterval(t);
17+
}
18+
}, 100);

0 commit comments

Comments
 (0)