Skip to content

Commit

Permalink
doc: document n-api callback scope usage
Browse files Browse the repository at this point in the history
Document that it is not necessary to open handle and/or callback scopes
inside finalizer, async work, thread-safe function etc. callbacks
unless for reasons documented in the section about object lifetime
management.

Link usage of callback signatures to their definition.

Fixes: nodejs#33893
  • Loading branch information
Gabriel Schulhof committed Jun 23, 2020
1 parent f6dbba8 commit e15ff2e
Showing 1 changed file with 36 additions and 16 deletions.
52 changes: 36 additions & 16 deletions doc/api/n-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ napi_status napi_set_instance_data(napi_env env,
* `[in] data`: The data item to make available to bindings of this instance.
* `[in] finalize_cb`: The function to call when the environment is being torn
down. The function receives `data` so that it might free it.
[`napi_finalize`][] provides more details.
* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
collection.

Expand Down Expand Up @@ -597,6 +598,7 @@ minimum lifetimes explicitly.
For more details, review the [Object lifetime management][].

### N-API callback types

#### napi_callback_info
<!-- YAML
added: v8.0.0
Expand All @@ -619,6 +621,9 @@ following signature:
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
```

Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside a `napi_callback` is not necessary.

#### napi_finalize
<!-- YAML
added: v8.0.0
Expand All @@ -637,6 +642,9 @@ typedef void (*napi_finalize)(napi_env env,
void* finalize_hint);
```

Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside the function body is not necessary.

#### napi_async_execute_callback
<!-- YAML
added: v8.0.0
Expand All @@ -649,12 +657,10 @@ operations. Callback functions must satisfy the following signature:
typedef void (*napi_async_execute_callback)(napi_env env, void* data);
```

Implementations of this function must avoid making N-API calls
that execute JavaScript or interact with
JavaScript objects. N-API
calls should be in the `napi_async_complete_callback` instead.
Do not use the `napi_env` parameter as it will likely
result in execution of JavaScript.
Implementations of this function must avoid making N-API calls that execute
JavaScript or interact with JavaScript objects. N-API calls should be in the
`napi_async_complete_callback` instead. Do not use the `napi_env` parameter as
it will likely result in execution of JavaScript.

#### napi_async_complete_callback
<!-- YAML
Expand All @@ -670,6 +676,9 @@ typedef void (*napi_async_complete_callback)(napi_env env,
void* data);
```

Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside the function body is not necessary.

#### napi_threadsafe_function_call_js
<!-- YAML
added: v10.6.0
Expand Down Expand Up @@ -713,6 +722,9 @@ typedef void (*napi_threadsafe_function_call_js)(napi_env env,
This pointer is managed entirely by the threads and this callback. Thus this
callback should free the data.

Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside the function body is not necessary.

## Error handling

N-API uses both return values and JavaScript exceptions for error handling.
Expand Down Expand Up @@ -1958,7 +1970,7 @@ napi_status napi_create_external(napi_env env,
* `[in] env`: The environment that the API is invoked under.
* `[in] data`: Raw pointer to the external data.
* `[in] finalize_cb`: Optional callback to call when the external value is being
collected.
collected. [`napi_finalize`][] provides more details.
* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
collection.
* `[out] result`: A `napi_value` representing an external value.
Expand Down Expand Up @@ -2002,7 +2014,7 @@ napi_create_external_arraybuffer(napi_env env,
`ArrayBuffer`.
* `[in] byte_length`: The length in bytes of the underlying buffer.
* `[in] finalize_cb`: Optional callback to call when the `ArrayBuffer` is being
collected.
collected. [`napi_finalize`][] provides more details.
* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
collection.
* `[out] result`: A `napi_value` representing a JavaScript `ArrayBuffer`.
Expand Down Expand Up @@ -2045,7 +2057,7 @@ napi_status napi_create_external_buffer(napi_env env,
size of the new buffer).
* `[in] data`: Raw pointer to the underlying buffer to copy from.
* `[in] finalize_cb`: Optional callback to call when the `ArrayBuffer` is being
collected.
collected. [`napi_finalize`][] provides more details.
* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
collection.
* `[out] result`: A `napi_value` representing a `node::Buffer`.
Expand Down Expand Up @@ -3572,16 +3584,16 @@ typedef struct {
If this is passed in, set `value` and `method` to `NULL` (since these members
won't be used). The given function is called implicitly by the runtime when
the property is accessed from JavaScript code (or if a get on the property is
performed using a N-API call).
performed using a N-API call). [`napi_callback`][] provides more details.
* `setter`: A function to call when a set access of the property is performed.
If this is passed in, set `value` and `method` to `NULL` (since these members
won't be used). The given function is called implicitly by the runtime when
the property is set from JavaScript code (or if a set on the property is
performed using a N-API call).
performed using a N-API call). [`napi_callback`][] provides more details.
* `method`: Set this to make the property descriptor object's `value`
property to be a JavaScript function represented by `method`. If this is
passed in, set `value`, `getter` and `setter` to `NULL` (since these members
won't be used).
won't be used). [`napi_callback`][] provides more details.
* `attributes`: The attributes associated with the particular property. See
[`napi_property_attributes`][].
* `data`: The callback data passed into `method`, `getter` and `setter` if this
Expand Down Expand Up @@ -4059,7 +4071,7 @@ napi_status napi_create_function(napi_env env,
* `[in] length`: The length of the `utf8name` in bytes, or `NAPI_AUTO_LENGTH` if
it is null-terminated.
* `[in] cb`: The native function which should be called when this function
object is invoked.
object is invoked. [`napi_callback`][] provides more details.
* `[in] data`: User-provided data context. This will be passed back into the
function when invoked later.
* `[out] result`: `napi_value` representing the JavaScript function object for
Expand Down Expand Up @@ -4293,8 +4305,8 @@ napi_status napi_define_class(napi_env env,
* `[in] length`: The length of the `utf8name` in bytes, or `NAPI_AUTO_LENGTH`
if it is null-terminated.
* `[in] constructor`: Callback function that handles constructing instances
of the class. (This should be a static method on the class, not an actual
C++ constructor function.)
of the class. This should be a static method on the class, not an actual
C++ constructor function. [`napi_callback`][] provides more details.
* `[in] data`: Optional data to be passed to the constructor callback as
the `data` property of the callback info.
* `[in] property_count`: Number of items in the `properties` array argument.
Expand Down Expand Up @@ -4356,6 +4368,7 @@ napi_status napi_wrap(napi_env env,
JavaScript object.
* `[in] finalize_cb`: Optional native callback that can be used to free the
native instance when the JavaScript object is ready for garbage-collection.
[`napi_finalize`][] provides more details.
* `[in] finalize_hint`: Optional contextual hint that is passed to the
finalize callback.
* `[out] result`: Optional reference to the wrapped object.
Expand Down Expand Up @@ -4464,6 +4477,7 @@ napi_status napi_add_finalizer(napi_env env,
object.
* `[in] finalize_cb`: Native callback that will be used to free the
native data when the JavaScript object is ready for garbage-collection.
[`napi_finalize`][] provides more details.
* `[in] finalize_hint`: Optional contextual hint that is passed to the
finalize callback.
* `[out] result`: Optional reference to the JavaScript object.
Expand Down Expand Up @@ -4571,7 +4585,8 @@ napi_status napi_create_async_work(napi_env env,
and can execute in parallel with the main event loop thread.
* `[in] complete`: The native function which will be called when the
asynchronous logic is completed or is cancelled. The given function is called
from the main event loop thread.
from the main event loop thread. [`napi_async_complete_callback`][] provides
more details.
* `[in] data`: User-provided data context. This will be passed back into the
execute and complete functions.
* `[out] result`: `napi_async_work*` which is the handle to the newly created
Expand Down Expand Up @@ -5248,6 +5263,7 @@ napi_create_threadsafe_function(napi_env env,
response to a call on a different thread. This callback will be called on the
main thread. If not given, the JavaScript function will be called with no
parameters and with `undefined` as its `this` value.
[`napi_threadsafe_function_call_js`][] provides more details.
* `[out] result`: The asynchronous thread-safe JavaScript function.

### napi_get_threadsafe_function_context
Expand Down Expand Up @@ -5455,7 +5471,9 @@ This API may only be called from the main thread.
[`init` hooks]: async_hooks.html#async_hooks_init_asyncid_type_triggerasyncid_resource
[`napi_add_env_cleanup_hook`]: #n_api_napi_add_env_cleanup_hook
[`napi_add_finalizer`]: #n_api_napi_add_finalizer
[`napi_async_complete_callback`]: #n_api_napi_async_complete_callback
[`napi_async_init`]: #n_api_napi_async_init
[`napi_callback`]: #n_api_napi_callback
[`napi_cancel_async_work`]: #n_api_napi_cancel_async_work
[`napi_close_callback_scope`]: #n_api_napi_close_callback_scope
[`napi_close_escapable_handle_scope`]: #n_api_napi_close_escapable_handle_scope
Expand All @@ -5470,6 +5488,7 @@ This API may only be called from the main thread.
[`napi_delete_async_work`]: #n_api_napi_delete_async_work
[`napi_delete_reference`]: #n_api_napi_delete_reference
[`napi_escape_handle`]: #n_api_napi_escape_handle
[`napi_finalize`]: #n_api_napi_finalize
[`napi_get_and_clear_last_exception`]: #n_api_napi_get_and_clear_last_exception
[`napi_get_array_length`]: #n_api_napi_get_array_length
[`napi_get_element`]: #n_api_napi_get_element
Expand All @@ -5491,6 +5510,7 @@ This API may only be called from the main thread.
[`napi_reference_unref`]: #n_api_napi_reference_unref
[`napi_set_instance_data`]: #n_api_napi_set_instance_data
[`napi_set_property`]: #n_api_napi_set_property
[`napi_threadsafe_function_call_js`]: #n_api_napi_threadsafe_function_call_js
[`napi_throw_error`]: #n_api_napi_throw_error
[`napi_throw_range_error`]: #n_api_napi_throw_range_error
[`napi_throw_type_error`]: #n_api_napi_throw_type_error
Expand Down

0 comments on commit e15ff2e

Please sign in to comment.