Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Incorrect loop->active_handles count when nested setTimeout calls have same value #25831

Description

@abbr

I maintain a c++ module deasync (originally written by @vkurchatkin) which essentially exposes uv_run to jsLand in order to address some use cases that cannot be handled by other async-2-sync modules. A problem was reported recently that when deasync is involved in nested setTimeout calls with same timeout value, the process hung. It is illustrated by code

var deasync = require('deasync');

function async(cb) {
  console.log('x');
  setTimeout(function () {
    console.log('y');
    cb(null, 'value');
    console.log('z');
  }, 8);
}

setTimeout(function () {
  console.log('A', deasync(async)());
}, 8); // changing 8 to, say 9, works

output

x
(hung)

Changing one of the timeout values of setTimeout yields expected output

x
y
z
A value

Problem is reproducible in latest Node version on at least Linux and Windows. I have run node in gdb session and found the problem is loop->active_handles has gone down to 0 after the inner setTimeout is called but before its handler is triggered, therefore the inner handler doesn't have a chance to run.

I think the cause is that timers of same timeout value are implemented using a linked list and only one handle is exposed to libuv. This handle is removed at the time the outer setTimeout handler is called.

By moving list.start(msecs, 0) in /lib/timers.js outside else block, I have verified the problem can be fixed. Will supply a PR later. What I am not clear is the impact of this change. Appreciate if someone can review the issue and my PR.

(P.S. I have read Node issue reporting guidelines and understand I am not supposed include dependencies. But deasync is simple, has no dependency by itself, and is easy to be re-factored into a dependency-less mixture of c++ and js code)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions