Skip to content

Infinite loop in timers.js #9756

@hassy

Description

@hassy
  • 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

node/lib/timers.js

Lines 514 to 519 in 6f75b66

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-bugIssues with confirmed bugs.timersIssues and PRs related to the timers subsystem / setImmediate, setInterval, setTimeout.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions