-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
node-api: generalize finalizer second pass callback #44141
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
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 :) |
mhdawson
left a comment
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 <[email protected]>
|
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 <[email protected]>
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 <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
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 <[email protected]> Reviewed-By: Michael Dawson <[email protected]>
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 <[email protected]>
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 <[email protected]>
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 <[email protected]>
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::Finalizeare 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