GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — node-api: document node-api shutdown finalization by legendecas · Pull Request #45903 · nodejs/node

Conversation

@legendecas

@legendecas legendecas commented Dec 18, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

As status quo, the cleanup hooks are invoked before the napi_finalize
callbacks at the exit of Node.js environments. This gives addons a
chance to release their resource in a proper order manually.

Document this behavior explicitly to advocate the usage on cleanup
hooks instead of relying on the implied invocation of napi_finalize
callbacks at shutdown.

This PR also unifies the term "Node.js instance" and "Agent" as "Node.js environment".

Fixes: #45088

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

bricss reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@legendecas
node-api: document node-api shutdown finalization
79fecec
As status quo, the cleanup hooks are invoked before the `napi_finalize`
callbacks at the exit of Node.js environments. This gives addons a
chance to release their resource in a proper order manually.

Document this behavior explicitly to advocate the usage on cleanup
hooks instead of relying on the implied invocation of `napi_finalize`
callbacks at shutdown.
@nodejs-github-bot

nodejs-github-bot commented Dec 18, 2022

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/node-api
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@nodejs-github-bot nodejs-github-bot added doc Issues and PRs related to Node.js documentation. node-api Issues and PRs related to Node-API. labels Dec 18, 2022
@legendecas legendecas mentioned this pull request Dec 18, 2022
(Typed)ThreadSafeFunction.Release() crashes renderer process on reload (& abort?) nodejs/node-addon-api#1109
Closed
mhdawson
mhdawson reviewed Dec 19, 2022
View reviewed changes
Comment thread doc/api/n-api.md
possible with JavaScript execution disallowed, like on the request of
[`worker.terminate()`][]. When the environment is being torn down, the
registered `napi_finalize` callbacks of JavaScript objects, Thread-safe
functions and environment instance data are invoked immediately and

@mhdawson mhdawson Dec 19, 2022

Copy link
Copy Markdown
Member

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.

Do you mean these run in parallel?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@legendecas legendecas Dec 22, 2022

Copy link
Copy Markdown
Member Author

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.

No, their napi_finalize callbacks can be run in an interleaving pattern, on the JavaScript thread.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
mhdawson
mhdawson reviewed Dec 19, 2022
View reviewed changes
Comment thread doc/api/n-api.md
registered cleanup hooks. In order to ensure a proper order of addon
finalization during environment shutdown to avoid use-after-free in the
`napi_finalize` callback, addons should register a cleanup hook with
`napi_add_env_cleanup_hook` and `napi_add_async_cleanup_hook` to manually

@mhdawson mhdawson Dec 19, 2022

Copy link
Copy Markdown
Member

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.

Can you expand a bit here? Is the suggestion to use the hooks instead of napi_finalize callback?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@legendecas legendecas Dec 22, 2022

Copy link
Copy Markdown
Member Author

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.

This part is specifically focused on the finalization at shutdown. Still, addons should set an napi_finalize callback to finalize the native objects properly.

However, their napi_finalize callbacks can be run in an interleaving pattern forcefully, regardless of if they are actually referenced. This would lead to the problem mentioned in nodejs/node-addon-api#1109:

Normally, we expect the order to be:

  1. create an ObjectWrap,
  2. create a ThreadSafeFunction and save it to a field of that ObjectWrap,
  3. release the ObjectWrap,
  4. release the ThreadSafeFunction in the ~ObjectWrap.

However, when the environment is shutting down, the order would be:

  1. create an ObjectWrap,
  2. create a ThreadSafeFunction and save it to a field of that ObjectWrap,
  3. env shutdown, run napi_finalize in reversed creation order,
  4. release the ThreadSafeFunction,
  5. release the ObjectWrap => crash as the ThreadSafeFunction has already been finalized.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mmomtchev mmomtchev Jan 17, 2023

Copy link
Copy Markdown
Contributor

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.

@legendecas Does this mean that I am supposed to maintain a central directory of all ThreadSafeFunction by environment so that I can Release in the cleanup hook because by the time the ObjectWrap destructor is called, it would be too late?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@mmomtchev mmomtchev Jan 17, 2023

Copy link
Copy Markdown
Contributor

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.

@legendecas in particular, if I use napi_add_async_cleanup_hook, can I delay the destruction of the environment until all ObjectWraps has been destroyed? Ie, will the destructors get called while Node is waiting for napi_remove_async_cleanup_hook? I strongly suggest that you do at least this, because otherwise this would mean that all ObjectWraps are to have a two-staged destruction with a C++ destructor and a, lets call it ::Destroy(), method which can be called both from the destructor and the environment cleanup hook. This would throw out of the window all the work done on the clean node-addon-api interface which aligns the JS object lifecycle with the C++ constructor/destructor.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@legendecas legendecas Feb 17, 2023

Copy link
Copy Markdown
Member Author

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.

@mmomtchev Does this mean that I am supposed to maintain a central directory of all ThreadSafeFunction by environment so that I can Release in the cleanup hook because by the time the ObjectWrap destructor is called, it would be too late?

If the ThreadSafeFunction is saved as a field of a c++ ObjectWrap, it should be released in the destructor of the ObjectWrap. So it is sufficient for an add-on to keep track of ObjectWraps and released them in a napi_cleanup_hook.

in particular, if I use napi_add_async_cleanup_hook, can I delay the destruction of the environment until all ObjectWraps has been destroyed? Ie, will the destructors get called while Node is waiting for napi_remove_async_cleanup_hook?

This is how napi_async_cleanup_hook_handle works now. If an napi_async_cleanup_hook_handle is still pending removal by napi_remove_async_cleanup_hook, the napi_env is not going to be destructed. This is verified with tests at #46692.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
jasnell
jasnell approved these changes Jan 17, 2023
View reviewed changes
mhdawson
mhdawson approved these changes Mar 17, 2023
View reviewed changes

@mhdawson mhdawson left a comment

Copy link
Copy Markdown
Member

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

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@legendecas legendecas added the commit-queue PRs queued for automated landing through the Commit Queue. label Mar 20, 2023
@nodejs-github-bot nodejs-github-bot removed the commit-queue PRs queued for automated landing through the Commit Queue. label Mar 20, 2023
@nodejs-github-bot
nodejs-github-bot merged commit 2984cc3 into nodejs:main Mar 20, 2023
@nodejs-github-bot

nodejs-github-bot commented Mar 20, 2023

Copy link
Copy Markdown
Collaborator

Landed in 2984cc3

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@legendecas
legendecas deleted the node-api/shutdown branch March 20, 2023 09:59
@RafaelGSS RafaelGSS mentioned this pull request Apr 3, 2023
2023-04-18, Version 20.0.0 (Current) #47381
Merged
RafaelGSS pushed a commit that referenced this pull request Apr 5, 2023
@legendecas @RafaelGSS
node-api: document node-api shutdown finalization
7195f23
As status quo, the cleanup hooks are invoked before the `napi_finalize`
callbacks at the exit of Node.js environments. This gives addons a
chance to release their resource in a proper order manually.

Document this behavior explicitly to advocate the usage on cleanup
hooks instead of relying on the implied invocation of `napi_finalize`
callbacks at shutdown.

PR-URL: #45903
Fixes: #45088
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@RafaelGSS RafaelGSS mentioned this pull request Apr 6, 2023
v19.9.0 proposal #47441
Merged
RafaelGSS pushed a commit that referenced this pull request Apr 7, 2023
@legendecas @RafaelGSS
node-api: document node-api shutdown finalization
55f3d21
As status quo, the cleanup hooks are invoked before the `napi_finalize`
callbacks at the exit of Node.js environments. This gives addons a
chance to release their resource in a proper order manually.

Document this behavior explicitly to advocate the usage on cleanup
hooks instead of relying on the implied invocation of `napi_finalize`
callbacks at shutdown.

PR-URL: #45903
Fixes: #45088
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
danielleadams pushed a commit that referenced this pull request Jul 6, 2023
@legendecas @danielleadams
node-api: document node-api shutdown finalization
6e66371
As status quo, the cleanup hooks are invoked before the `napi_finalize`
callbacks at the exit of Node.js environments. This gives addons a
chance to release their resource in a proper order manually.

Document this behavior explicitly to advocate the usage on cleanup
hooks instead of relying on the implied invocation of `napi_finalize`
callbacks at shutdown.

PR-URL: #45903
Fixes: #45088
Reviewed-By: James M Snell <[email protected]>
Reviewed-By: Michael Dawson <[email protected]>
@danielleadams danielleadams mentioned this pull request Jul 10, 2023
v18.17.0 release proposal #48694
Merged
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@jasnell jasnell jasnell approved these changes
+2 more reviewers
@mmomtchev mmomtchev mmomtchev left review comments
@mhdawson mhdawson mhdawson approved these changes
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

doc Issues and PRs related to Node.js documentation. node-api Issues and PRs related to Node-API.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

ObjectWrap destructors run after CleanupHook

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@legendecas @nodejs-github-bot @jasnell @mhdawson @mmomtchev
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.