-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
node-api: generalize finalizer second pass callback #44141
Conversation
Review requested:
|
486add4
to
40562fc
Compare
e9ac1e2
to
d71cdd6
Compare
This comment was marked as outdated.
This comment was marked as outdated.
d71cdd6
to
2a14bf3
Compare
if (!finalization_scheduled) { | ||
finalization_scheduled = true; | ||
Ref(); | ||
node_env()->SetImmediate([this](node::Environment* node_env) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Capturing this
is not safe: if the lambda is not executed, then the env
instance is never released. It would be better to use the EnvRefHolder
here which is being deleted in this PR from js_native_api_v8.h. This way the Unref() is always called when the lambda is released.
Also, when we call the Unref()
below we must be prepared that it was the last Unref()
that causes the env
instance destruction. In such case the DrainFinalizerQueue()
may be called against deleted object and cause issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The callback of Environment::SetImmediate
is deemed to be called. So we don't need additional setups for the condition that the callback is not invoked.
while (!pending_finalizers.empty()) { | ||
v8impl::RefTracker* ref_tracker = *pending_finalizers.begin(); | ||
pending_finalizers.erase(ref_tracker); | ||
ref_tracker->Finalize(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do we handle uncaught JS exceptions? Previously the SetImmediate
code was taking care about the exceptions. It may be worth adding a test where we have a few finalizers running and they all throw JS exceptions. The JS code should handle and ignore those exceptions - we must see all the finalizers executed.
Also, we need to test that if JS does not handle the uncaught exceptions, then we crash as usual.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node_napi_env__::CallFinalizer
still handles JS exception. Native SetImmediate
doesn't handle JS exceptions.
9416d37
to
c6b1b47
Compare
@mhdawson thank you for verifying the patch with node-addon-api test sets. I believe the problem here is what
However, I found that on the main branch, when the So basically, when the
|
c6b1b47
to
65fce2b
Compare
Generalize the finalizer's second pass callback to make it cancellable and simplify the code around the second pass callback. With this change, it is determined that Reference::Finalize or RefBase::Finalize are called once, either from the env's shutdown, or from the env's second pass callback. All existing node-api js tests should pass without a touch. The js_native_api cctest is no longer applicable with this change, just removing it.
65fce2b
to
344493a
Compare
@mhdawson updated, PTAL again, thank you :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, I ran the node-addon-api tests 10000 times with these changes and they all passed.
Generalize the finalizer's second pass callback to make it cancellable and simplify the code around the second pass callback. With this change, it is determined that Reference::Finalize or RefBase::Finalize are called once, either from the env's shutdown, or from the env's second pass callback. All existing node-api js tests should pass without a touch. The js_native_api cctest is no longer applicable with this change, just removing it. PR-URL: #44141 Refs: #44071 Reviewed-By: Michael Dawson <midawson@redhat.com>
Landed in f14fa1b |
Generalize the finalizer's second pass callback to make it cancellable and simplify the code around the second pass callback. With this change, it is determined that Reference::Finalize or RefBase::Finalize are called once, either from the env's shutdown, or from the env's second pass callback. All existing node-api js tests should pass without a touch. The js_native_api cctest is no longer applicable with this change, just removing it. PR-URL: #44141 Refs: #44071 Reviewed-By: Michael Dawson <midawson@redhat.com>
Functions declared in anonymous namespaces are not necessarily to be marked as static. PR-URL: nodejs/node#44301 Refs: nodejs/node#44141 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michael Dawson <midawson@redhat.com>
Functions declared in anonymous namespaces are not necessarily to be marked as static. PR-URL: nodejs/node#44301 Refs: nodejs/node#44141 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Michael Dawson <midawson@redhat.com>
Generalize the finalizer's second pass callback to make it cancellable and simplify the code around the second pass callback. With this change, it is determined that Reference::Finalize or RefBase::Finalize are called once, either from the env's shutdown, or from the env's second pass callback. All existing node-api js tests should pass without a touch. The js_native_api cctest is no longer applicable with this change, just removing it. PR-URL: #44141 Refs: #44071 Reviewed-By: Michael Dawson <midawson@redhat.com>
Generalize the finalizer's second pass callback to make it cancellable and simplify the code around the second pass callback. With this change, it is determined that Reference::Finalize or RefBase::Finalize are called once, either from the env's shutdown, or from the env's second pass callback. All existing node-api js tests should pass without a touch. The js_native_api cctest is no longer applicable with this change, just removing it. PR-URL: #44141 Refs: #44071 Reviewed-By: Michael Dawson <midawson@redhat.com>
Generalize the finalizer's second pass callback to make it cancellable and simplify the code around the second pass callback. With this change, it is determined that Reference::Finalize or RefBase::Finalize are called once, either from the env's shutdown, or from the env's second pass callback. All existing node-api js tests should pass without a touch. The js_native_api cctest is no longer applicable with this change, just removing it. PR-URL: #44141 Refs: #44071 Reviewed-By: Michael Dawson <midawson@redhat.com>
Generalize the finalizer's second pass callback to make it cancellable and simplify the code around the second pass callback.
With this change, it is determined that
Reference::Finalize
/RefBase::Finalize
are called once, either from the env's shutdown, or from the env's second pass callback.All existing node-api js tests should pass without a touch. The js_native_api cctest is no longer applicable with this change, just removing it.
Refs: #44071