- Version: 6.8.1 and later
- Platform: tested on OSX & Linux, probably all platforms
- Subsystem: timers
v6.8.1 and above will all hang when the following code is run:
var i1 = setImmediate(function() {
console.log('i1 cb');
clearImmediate(i2);
clearImmediate(i3);
});
var i2 = setImmediate(function() {
console.log('i2 cb');
});
var i3 = setImmediate(function() {
console.log('i3 cb');
});
console.log('All set');
An example run of the code above:
hassy@mdb $ node -v
v4.3.2
hassy@mdb $ node isolated.js
All set
i1 cb
#
# The process exits immediately.
#
hassy@mdb $ nvm use 6.8.1
hassy@mdb $ node -v
v6.8.1
hassy@mdb $ node isolated.js
All set
i1 cb
#
# The process won't exit. top shows it using 98%+ CPU.
#
The cause is Node entering into an infinite loop here when immediate._onImmediate is null:
(source: https://github.com/nodejs/node/blob/master/lib/timers.js#L580-L587)
while (immediate) {
domain = immediate.domain;
if (!immediate._onImmediate)
continue;
This happens when the immediate referred to by next gets cleared.
The issue first manifests itself in this commit: 42158a0
The if branch that causes an infinite loop was first introduced in
|
while (L.isEmpty(queue) === false) { |
|
immediate = L.shift(queue); |
|
domain = immediate.domain; |
|
|
|
if (!immediate._onImmediate) |
|
continue; |
but is obsolete now since the value of
immediate will not change once the condition is hit.
I'll send a PR to go along with this with a proposed fix.
EDIT 1: Simplified the test case.
v6.8.1 and above will all hang when the following code is run:
An example run of the code above:
The cause is Node entering into an infinite loop here when immediate._onImmediate is
null:(source: https://github.com/nodejs/node/blob/master/lib/timers.js#L580-L587)
This happens when the immediate referred to by
nextgets cleared.The issue first manifests itself in this commit: 42158a0
The
ifbranch that causes an infinite loop was first introduced innode/lib/timers.js
Lines 514 to 519 in 6f75b66
immediatewill not change once the condition is hit.I'll send a PR to go along with this with a proposed fix.
EDIT 1: Simplified the test case.