You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 22, 2023. It is now read-only.
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)