mirror of https://github.com/lukechilds/node.git
Browse Source
The timer handle is reused when it is unrefed in order to avoid new callback in beforeExit(#3407). If it is unrefed within a setInterval callback, the reused timer handle is closed so that setInterval no longer keep working. This fix does not close the handle in case of setInterval. PR-URL: https://github.com/nodejs/node/pull/11646 Reviewed-By: Julien Gilli <jgilli@nodejs.org> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>v6.x
committed by
Myles Borins
2 changed files with 68 additions and 1 deletions
@ -0,0 +1,61 @@ |
|||
'use strict'; |
|||
// Checks that setInterval timers keep running even when they're
|
|||
// unrefed within their callback.
|
|||
|
|||
require('../common'); |
|||
const assert = require('assert'); |
|||
const net = require('net'); |
|||
|
|||
let counter1 = 0; |
|||
let counter2 = 0; |
|||
|
|||
// Test1 checks that clearInterval works as expected for a timer
|
|||
// unrefed within its callback: it removes the timer and its callback
|
|||
// is not called anymore. Note that the only reason why this test is
|
|||
// robust is that:
|
|||
// 1. the repeated timer it creates has a delay of 1ms
|
|||
// 2. when this test is completed, another test starts that creates a
|
|||
// new repeated timer with the same delay (1ms)
|
|||
// 3. because of the way timers are implemented in libuv, if two
|
|||
// repeated timers A and B are created in that order with the same
|
|||
// delay, it is guaranteed that the first occurrence of timer A
|
|||
// will fire before the first occurrence of timer B
|
|||
// 4. as a result, when the timer created by Test2 fired 11 times, if
|
|||
// the timer created by Test1 hadn't been removed by clearInterval,
|
|||
// it would have fired 11 more times, and the assertion in the
|
|||
// process'exit event handler would fail.
|
|||
function Test1() { |
|||
// server only for maintaining event loop
|
|||
const server = net.createServer().listen(0); |
|||
|
|||
const timer1 = setInterval(() => { |
|||
timer1.unref(); |
|||
if (counter1++ === 3) { |
|||
clearInterval(timer1); |
|||
server.close(() => { |
|||
Test2(); |
|||
}); |
|||
} |
|||
}, 1); |
|||
} |
|||
|
|||
|
|||
// Test2 checks setInterval continues even if it is unrefed within
|
|||
// timer callback. counter2 continues to be incremented more than 11
|
|||
// until server close completed.
|
|||
function Test2() { |
|||
// server only for maintaining event loop
|
|||
const server = net.createServer().listen(0); |
|||
|
|||
const timer2 = setInterval(() => { |
|||
timer2.unref(); |
|||
if (counter2++ === 3) |
|||
server.close(); |
|||
}, 1); |
|||
} |
|||
|
|||
process.on('exit', () => { |
|||
assert.strictEqual(counter1, 4); |
|||
}); |
|||
|
|||
Test1(); |
Loading…
Reference in new issue