Skip to content

Commit

Permalink
node-api: document node-api shutdown finalization
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
legendecas authored and danielleadams committed Jul 6, 2023
1 parent 9a11788 commit 6e66371
Showing 1 changed file with 31 additions and 14 deletions.
45 changes: 31 additions & 14 deletions doc/api/n-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,11 @@ may be called multiple times, from multiple contexts, and even concurrently from
multiple threads.

Native addons may need to allocate global state which they use during
their entire life cycle such that the state must be unique to each instance of
the addon.
their life cycle of an Node.js environment such that the state can be
unique to each instance of the addon.

To this end, Node-API provides a way to allocate data such that its life cycle
is tied to the life cycle of the Agent.
To this end, Node-API provides a way to associate data such that its life cycle
is tied to the life cycle of a Node.js environment.

### `napi_set_instance_data`

Expand Down Expand Up @@ -510,11 +510,11 @@ napi_status napi_set_instance_data(napi_env env,

Returns `napi_ok` if the API succeeded.

This API associates `data` with the currently running Agent. `data` can later
be retrieved using `napi_get_instance_data()`. Any existing data associated with
the currently running Agent which was set by means of a previous call to
`napi_set_instance_data()` will be overwritten. If a `finalize_cb` was provided
by the previous call, it will not be called.
This API associates `data` with the currently running Node.js environment. `data`
can later be retrieved using `napi_get_instance_data()`. Any existing data
associated with the currently running Node.js environment which was set by means
of a previous call to `napi_set_instance_data()` will be overwritten. If a
`finalize_cb` was provided by the previous call, it will not be called.

### `napi_get_instance_data`

Expand All @@ -532,13 +532,13 @@ napi_status napi_get_instance_data(napi_env env,

* `[in] env`: The environment that the Node-API call is invoked under.
* `[out] data`: The data item that was previously associated with the currently
running Agent by a call to `napi_set_instance_data()`.
running Node.js environment by a call to `napi_set_instance_data()`.

Returns `napi_ok` if the API succeeded.

This API retrieves data that was previously associated with the currently
running Agent via `napi_set_instance_data()`. If no data is set, the call will
succeed and `data` will be set to `NULL`.
running Node.js environment via `napi_set_instance_data()`. If no data is set,
the call will succeed and `data` will be set to `NULL`.

## Basic Node-API data types

Expand Down Expand Up @@ -1799,11 +1799,11 @@ If still valid, this API returns the `napi_value` representing the
JavaScript `Object` associated with the `napi_ref`. Otherwise, result
will be `NULL`.

### Cleanup on exit of the current Node.js instance
### Cleanup on exit of the current Node.js environment

While a Node.js process typically releases all its resources when exiting,
embedders of Node.js, or future Worker support, may require addons to register
clean-up hooks that will be run once the current Node.js instance exits.
clean-up hooks that will be run once the current Node.js environment exits.

Node-API provides functions for registering and un-registering such callbacks.
When those callbacks are run, all resources that are being held by the addon
Expand Down Expand Up @@ -1929,6 +1929,22 @@ the hook from being executed, unless it has already started executing.
This must be called on any `napi_async_cleanup_hook_handle` value obtained
from [`napi_add_async_cleanup_hook`][].

### Finalization on the exit of the Node.js environment

The Node.js environment may be torn down at an arbitrary time as soon as
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
independently.

The invocation of `napi_finalize` callbacks are scheduled after the manually
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
release the allocated resource in a proper order.

## Module registration

Node-API modules are registered in a manner similar to other modules
Expand Down Expand Up @@ -6431,6 +6447,7 @@ the add-on's file name during loading.
[`process.release`]: process.md#processrelease
[`uv_ref`]: https://docs.libuv.org/en/v1.x/handle.html#c.uv_ref
[`uv_unref`]: https://docs.libuv.org/en/v1.x/handle.html#c.uv_unref
[`worker.terminate()`]: worker_threads.md#workerterminate
[async_hooks `type`]: async_hooks.md#type
[context-aware addons]: addons.md#context-aware-addons
[docs]: https://github.com/nodejs/node-addon-api#api-documentation
Expand Down

0 comments on commit 6e66371

Please sign in to comment.