async_hooks: fix nested hooks mutation#14143
async_hooks: fix nested hooks mutation#14143AndreasMadsen wants to merge 7 commits intonodejs:masterfrom AndreasMadsen:async-hooks-fix-nested-mutation
Conversation
There was a problem hiding this comment.
You kept crypto here, was that intentional? If so, it probably needs a guard for skipping the test if appropriate
There was a problem hiding this comment.
That is from the blocking PR, I will rebase once that is fixed.
lib/async_hooks.js
Outdated
There was a problem hiding this comment.
I'm worried that doing reference counting is too fragile.
Why not replace the for either with a .forEach for with a for (const hook of Array.from(active_hooks_array))
There was a problem hiding this comment.
I'm worried that doing reference counting is too fragile.
Could you be more explicit?
edit: Just to avoid confusion, this is not a reference counting it is a depth counting.
Why not replace the for either with a
.forEach
.forEach is not resistant to mutation.
const a = [1,2,3];
a.forEach(function (value) {
process._rawDebug(value);
a.pop();
});prints 1 2.
with a
for (const hook of Array.from(active_hooks_array))
Array copy is too slow. When async_hooks is enabled this is the hottest code path we have.
There was a problem hiding this comment.
Ack. I was sure .forEach iterated over a fixed array (it just ignores newly added elements)
lib/async_hooks.js
Outdated
There was a problem hiding this comment.
nit: Since we are going with depth counting, IMHO the decrement should be in a finally clause
There was a problem hiding this comment.
I guess, but there is no way to escape fatalError so the code will never be executed.
The try catch finally order is:
try {
throw new Error();
} catch (e) {
console.log('catch');
} finally {
console.log('finally');
}outputs catch finally.
There was a problem hiding this comment.
I guess, but there is no way to escape fatalError so the code will never be executed.
At the moment... If at some point we'll enable a fatalError trap this will break. Better to be explicit about these.
Reference/depth counting only works if it's ACID
lib/async_hooks.js
Outdated
This fixes an error that could occure by nesting async_hooks calls
In some cases restoreTmpHooks is called too early, this causes active_hooks_array to change during execution of the init hooks.
for when node is compiled without crypto support
trevnorris
left a comment
There was a problem hiding this comment.
Thanks much. Especially for the additional code comment in init(). Have a non-blocking nit to change the processing_hooks code comment to explain that it's a depth counter.
| // sure active_hooks_array isn't altered in mid execution if another hook is | ||
| // added or removed. | ||
| var processing_hook = false; | ||
| var processing_hook = 0; |
There was a problem hiding this comment.
Possibly change comment above from simply
Track whether a hook [...]
to something like
Use a counter to track [...] and prevent nested calls [...]
|
Fixed the nit. I had to use some artistic freedom to fit in the "prevent nested calls" part. But the meaning should be the same. |
|
landed in f94fd0c |
|
@AndreasMadsen Awesome. Thanks for adding the comment changes. |
In some cases restoreTmpHooks is called too early, this causes active_hooks_array to change during execution of the init hooks. PR-URL: #14143 Ref: #14054 (comment) Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
In some cases restoreTmpHooks is called too early, this causes active_hooks_array to change during execution of the init hooks. PR-URL: #14143 Ref: #14054 (comment) Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
async_hooks
In some cases
restoreTmpHooksis called too early, this causesactive_hooks_arrayto change during execution of the init hooks.This depends on #14054