node-addon-api 2.0.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.clang-format +111 -0
- package/.github/workflows/ci.yml +55 -0
- package/.github/workflows/linter.yml +24 -0
- package/.github/workflows/stale.yml +18 -0
- package/.travis.yml +1 -5
- package/CHANGELOG.md +237 -23
- package/README.md +101 -31
- package/appveyor.yml +3 -14
- package/benchmark/README.md +47 -0
- package/benchmark/binding.gyp +25 -0
- package/benchmark/function_args.cc +217 -0
- package/benchmark/function_args.js +60 -0
- package/benchmark/index.js +34 -0
- package/benchmark/property_descriptor.cc +91 -0
- package/benchmark/property_descriptor.js +37 -0
- package/common.gypi +21 -0
- package/doc/addon.md +157 -0
- package/doc/array.md +81 -0
- package/doc/array_buffer.md +20 -0
- package/doc/async_context.md +1 -1
- package/doc/async_worker.md +34 -5
- package/doc/{async_progress_worker.md → async_worker_variants.md} +236 -23
- package/doc/bigint.md +7 -2
- package/doc/boolean.md +5 -1
- package/doc/buffer.md +4 -0
- package/doc/checker-tool.md +1 -1
- package/doc/class_property_descriptor.md +3 -3
- package/doc/creating_a_release.md +6 -6
- package/doc/dataview.md +4 -0
- package/doc/date.md +2 -2
- package/doc/env.md +69 -0
- package/doc/error.md +5 -0
- package/doc/escapable_handle_scope.md +1 -1
- package/doc/external.md +4 -0
- package/doc/function.md +111 -3
- package/doc/function_reference.md +1 -1
- package/doc/handle_scope.md +1 -1
- package/doc/hierarchy.md +91 -0
- package/doc/instance_wrap.md +408 -0
- package/doc/name.md +29 -0
- package/doc/number.md +1 -1
- package/doc/object.md +44 -1
- package/doc/object_lifetime_management.md +2 -2
- package/doc/object_reference.md +1 -1
- package/doc/object_wrap.md +220 -216
- package/doc/prebuild_tools.md +2 -2
- package/doc/promises.md +5 -0
- package/doc/property_descriptor.md +67 -12
- package/doc/setup.md +1 -2
- package/doc/string.md +5 -1
- package/doc/symbol.md +5 -1
- package/doc/threadsafe.md +121 -0
- package/doc/threadsafe_function.md +16 -46
- package/doc/typed_array.md +4 -0
- package/doc/typed_array_of.md +4 -0
- package/doc/typed_threadsafe_function.md +307 -0
- package/doc/value.md +166 -104
- package/doc/version_management.md +2 -2
- package/except.gypi +16 -0
- package/index.js +7 -41
- package/napi-inl.h +1685 -464
- package/napi.h +606 -141
- package/node_api.gyp +9 -0
- package/noexcept.gypi +16 -0
- package/{src/nothing.c → nothing.c} +0 -0
- package/package-support.json +21 -0
- package/package.json +106 -2
- package/tools/README.md +12 -6
- package/tools/clang-format.js +47 -0
- package/tools/conversion.js +4 -8
- package/doc/Doxyfile +0 -2450
- package/doc/basic_types.md +0 -423
- package/doc/working_with_javascript_values.md +0 -14
- package/external-napi/node_api.h +0 -7
- package/src/node_api.cc +0 -3655
- package/src/node_api.gyp +0 -21
- package/src/node_api.h +0 -588
- package/src/node_api_types.h +0 -115
- package/src/node_internals.cc +0 -142
- package/src/node_internals.h +0 -157
- package/src/util-inl.h +0 -38
- package/src/util.h +0 -7
package/doc/prebuild_tools.md
CHANGED
|
@@ -5,8 +5,8 @@ In order to install a native add-on it's important to have all the necessary
|
|
|
5
5
|
dependencies installed and well configured (see the [setup](setup.md) section).
|
|
6
6
|
The end-user will need to compile the add-on when they will do an `npm install`
|
|
7
7
|
and in some cases this could create problems. To avoid the compilation process it's
|
|
8
|
-
possible to
|
|
9
|
-
and architectures. The prebuild tools help to create and
|
|
8
|
+
possible to distribute the native add-on in pre-built form for different platform
|
|
9
|
+
and architectures. The prebuild tools help to create and distribute the pre-built
|
|
10
10
|
form of a native add-on.
|
|
11
11
|
|
|
12
12
|
The following list report known tools that are compatible with **N-API**:
|
package/doc/promises.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Promise
|
|
2
2
|
|
|
3
|
+
Class `Napi::Promise` inherits from class [`Napi::Object`][].
|
|
4
|
+
|
|
3
5
|
The `Napi::Promise` class, along with its `Napi::Promise::Deferred` class, implement the ability to create, resolve, and reject Promise objects.
|
|
4
6
|
|
|
5
7
|
The basic approach is to create a `Napi::Promise::Deferred` object and return to your caller the value returned by the `Napi::Promise::Deferred::Promise` method. For example:
|
|
@@ -72,3 +74,6 @@ void Napi::Promise::Deferred::Reject(napi_value value) const;
|
|
|
72
74
|
Rejects the Promise object held by the `Napi::Promise::Deferred` object.
|
|
73
75
|
|
|
74
76
|
* `[in] value`: The N-API primitive value with which to reject the `Napi::Promise`.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
[`Napi::Object`]: ./object.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Property Descriptor
|
|
2
2
|
|
|
3
|
-
A [`Napi::Object`](object.md) can be assigned
|
|
3
|
+
A [`Napi::Object`](object.md) can be assigned properties via its [`DefineProperty`](object.md#defineproperty) and [`DefineProperties`](object.md#defineproperties) functions, which take PropertyDescriptor(s) as their parameters. The `Napi::PropertyDescriptor` can contain either values or functions, which are then assigned to the `Napi::Object`. Note that a single instance of a `Napi::PropertyDescriptor` class can only contain either one value, or at most two functions. PropertyDescriptors can only be created through the class methods [`Accessor`](#accessor), [`Function`](#function), or [`Value`](#value), each of which return a new static instance of a `Napi::PropertyDescriptor`.
|
|
4
4
|
|
|
5
5
|
## Example
|
|
6
6
|
|
|
@@ -26,15 +26,9 @@ Void Init(Env env) {
|
|
|
26
26
|
Object obj = Object::New(env);
|
|
27
27
|
|
|
28
28
|
// Accessor
|
|
29
|
-
PropertyDescriptor pd1 = PropertyDescriptor::Accessor(
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
TestGetter);
|
|
33
|
-
PropertyDescriptor pd2 = PropertyDescriptor::Accessor(env,
|
|
34
|
-
obj,
|
|
35
|
-
"pd2",
|
|
36
|
-
TestGetter,
|
|
37
|
-
TestSetter);
|
|
29
|
+
PropertyDescriptor pd1 = PropertyDescriptor::Accessor<TestGetter>("pd1");
|
|
30
|
+
PropertyDescriptor pd2 =
|
|
31
|
+
PropertyDescriptor::Accessor<TestGetter, TestSetter>("pd2");
|
|
38
32
|
// Function
|
|
39
33
|
PropertyDescriptor pd3 = PropertyDescriptor::Function(env,
|
|
40
34
|
"function",
|
|
@@ -51,6 +45,26 @@ Void Init(Env env) {
|
|
|
51
45
|
}
|
|
52
46
|
```
|
|
53
47
|
|
|
48
|
+
## Types
|
|
49
|
+
|
|
50
|
+
### PropertyDescriptor::GetterCallback
|
|
51
|
+
|
|
52
|
+
```cpp
|
|
53
|
+
typedef Napi::Value (*GetterCallback)(const Napi::CallbackInfo& info);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
This is the signature of a getter function to be passed as a template parameter
|
|
57
|
+
to `PropertyDescriptor::Accessor`.
|
|
58
|
+
|
|
59
|
+
### PropertyDescriptor::SetterCallback
|
|
60
|
+
|
|
61
|
+
```cpp
|
|
62
|
+
typedef void (*SetterCallback)(const Napi::CallbackInfo& info);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
This is the signature of a setter function to be passed as a template parameter
|
|
66
|
+
to `PropertyDescriptor::Accessor`.
|
|
67
|
+
|
|
54
68
|
## Methods
|
|
55
69
|
|
|
56
70
|
### Constructor
|
|
@@ -63,6 +77,47 @@ Napi::PropertyDescriptor::PropertyDescriptor (napi_property_descriptor desc);
|
|
|
63
77
|
|
|
64
78
|
### Accessor
|
|
65
79
|
|
|
80
|
+
```cpp
|
|
81
|
+
template <Napi::PropertyDescriptor::GetterCallback Getter>
|
|
82
|
+
static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (___ name,
|
|
83
|
+
napi_property_attributes attributes = napi_default,
|
|
84
|
+
void* data = nullptr);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
* `[template] Getter`: A getter function.
|
|
88
|
+
* `[in] attributes`: Potential attributes for the getter function.
|
|
89
|
+
* `[in] data`: A pointer to data of any type, default is a null pointer.
|
|
90
|
+
|
|
91
|
+
Returns a PropertyDescriptor that contains a read-only property.
|
|
92
|
+
|
|
93
|
+
The name of the property can be any of the following types:
|
|
94
|
+
- `const char*`
|
|
95
|
+
- `const std::string &`
|
|
96
|
+
- `napi_value value`
|
|
97
|
+
- `Napi::Name`
|
|
98
|
+
|
|
99
|
+
```cpp
|
|
100
|
+
template <
|
|
101
|
+
Napi::PropertyDescriptor::GetterCallback Getter,
|
|
102
|
+
Napi::PropertyDescriptor::SetterCallback Setter>
|
|
103
|
+
static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (___ name,
|
|
104
|
+
napi_property_attributes attributes = napi_default,
|
|
105
|
+
void* data = nullptr);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
* `[template] Getter`: A getter function.
|
|
109
|
+
* `[template] Setter`: A setter function.
|
|
110
|
+
* `[in] attributes`: Potential attributes for the getter function.
|
|
111
|
+
* `[in] data`: A pointer to data of any type, default is a null pointer.
|
|
112
|
+
|
|
113
|
+
Returns a PropertyDescriptor that contains a read-write property.
|
|
114
|
+
|
|
115
|
+
The name of the property can be any of the following types:
|
|
116
|
+
- `const char*`
|
|
117
|
+
- `const std::string &`
|
|
118
|
+
- `napi_value value`
|
|
119
|
+
- `Napi::Name`
|
|
120
|
+
|
|
66
121
|
```cpp
|
|
67
122
|
static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (___ name,
|
|
68
123
|
Getter getter,
|
|
@@ -95,7 +150,7 @@ static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (
|
|
|
95
150
|
void *data = nullptr);
|
|
96
151
|
```
|
|
97
152
|
|
|
98
|
-
* `[in] env`: The
|
|
153
|
+
* `[in] env`: The environment in which to create this accessor.
|
|
99
154
|
* `[in] object`: The object on which the accessor will be defined.
|
|
100
155
|
* `[in] name`: The name used for the getter function.
|
|
101
156
|
* `[in] getter`: A getter function.
|
|
@@ -144,7 +199,7 @@ static Napi::PropertyDescriptor Napi::PropertyDescriptor::Accessor (
|
|
|
144
199
|
void *data = nullptr);
|
|
145
200
|
```
|
|
146
201
|
|
|
147
|
-
* `[in] env`: The
|
|
202
|
+
* `[in] env`: The environment in which to create this accessor.
|
|
148
203
|
* `[in] object`: The object on which the accessor will be defined.
|
|
149
204
|
* `[in] name`: The name of the getter and setter function.
|
|
150
205
|
* `[in] getter`: The getter function.
|
package/doc/setup.md
CHANGED
|
@@ -26,8 +26,7 @@ To use **N-API** in a native module:
|
|
|
26
26
|
2. Reference this package's include directory and gyp file in `binding.gyp`:
|
|
27
27
|
|
|
28
28
|
```gyp
|
|
29
|
-
'include_dirs': ["
|
|
30
|
-
'dependencies': ["<!(node -p \"require('node-addon-api').gyp\")"],
|
|
29
|
+
'include_dirs': ["<!(node -p \"require('node-addon-api').include_dir\")"],
|
|
31
30
|
```
|
|
32
31
|
|
|
33
32
|
3. Decide whether the package will enable C++ exceptions in the N-API wrapper.
|
package/doc/string.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# String
|
|
2
2
|
|
|
3
|
+
Class `Napi::String` inherits from class [`Napi::Name`][].
|
|
4
|
+
|
|
3
5
|
## Constructor
|
|
4
6
|
|
|
5
7
|
```cpp
|
|
@@ -62,7 +64,7 @@ Napi::String::New(napi_env env, const char16_t* value, size_t length);
|
|
|
62
64
|
|
|
63
65
|
- `[in] env`: The `napi_env` environment in which to construct the `Napi::Value` object.
|
|
64
66
|
- `[in] value`: The C++ primitive from which to instantiate the `Napi::Value`. `value` may be any of:
|
|
65
|
-
- `std::string&` - represents
|
|
67
|
+
- `std::string&` - represents a UTF8 string.
|
|
66
68
|
- `std::u16string&` - represents a UTF16-LE string.
|
|
67
69
|
- `const char*` - represents a UTF8 string.
|
|
68
70
|
- `const char16_t*` - represents a UTF16-LE string.
|
|
@@ -87,3 +89,5 @@ std::u16string Napi::String::Utf16Value() const;
|
|
|
87
89
|
```
|
|
88
90
|
|
|
89
91
|
Returns a UTF-16 encoded C++ string.
|
|
92
|
+
|
|
93
|
+
[`Napi::Name`]: ./name.md
|
package/doc/symbol.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Symbol
|
|
2
2
|
|
|
3
|
+
Class `Napi::Symbol` inherits from class [`Napi::Name`][].
|
|
4
|
+
|
|
3
5
|
## Methods
|
|
4
6
|
|
|
5
7
|
### Constructor
|
|
@@ -23,7 +25,7 @@ Napi::Symbol::New(napi_env env, napi_value description);
|
|
|
23
25
|
- `[in] env`: The `napi_env` environment in which to construct the `Napi::Symbol` object.
|
|
24
26
|
- `[in] value`: The C++ primitive which represents the description hint for the `Napi::Symbol`.
|
|
25
27
|
`description` may be any of:
|
|
26
|
-
- `std::string&` -
|
|
28
|
+
- `std::string&` - UTF8 string description.
|
|
27
29
|
- `const char*` - represents a UTF8 string description.
|
|
28
30
|
- `String` - Node addon API String description.
|
|
29
31
|
- `napi_value` - N-API `napi_value` description.
|
|
@@ -42,3 +44,5 @@ static Napi::Symbol Napi::Symbol::WellKnown(napi_env env, const std::string& nam
|
|
|
42
44
|
|
|
43
45
|
Returns a `Napi::Symbol` representing a well-known `Symbol` from the
|
|
44
46
|
`Symbol` registry.
|
|
47
|
+
|
|
48
|
+
[`Napi::Name`]: ./name.md
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Thread-safe Functions
|
|
2
|
+
|
|
3
|
+
JavaScript functions can normally only be called from a native addon's main
|
|
4
|
+
thread. If an addon creates additional threads, then node-addon-api functions
|
|
5
|
+
that require a `Napi::Env`, `Napi::Value`, or `Napi::Reference` must not be
|
|
6
|
+
called from those threads.
|
|
7
|
+
|
|
8
|
+
When an addon has additional threads and JavaScript functions need to be invoked
|
|
9
|
+
based on the processing completed by those threads, those threads must
|
|
10
|
+
communicate with the addon's main thread so that the main thread can invoke the
|
|
11
|
+
JavaScript function on their behalf. The thread-safe function APIs provide an
|
|
12
|
+
easy way to do this. These APIs provide two types --
|
|
13
|
+
[`Napi::ThreadSafeFunction`](threadsafe_function.md) and
|
|
14
|
+
[`Napi::TypedThreadSafeFunction`](typed_threadsafe_function.md) -- as well as
|
|
15
|
+
APIs to create, destroy, and call objects of this type. The differences between
|
|
16
|
+
the two are subtle and are [highlighted below](#implementation-differences).
|
|
17
|
+
Regardless of which type you choose, the APIs between the two are similar.
|
|
18
|
+
|
|
19
|
+
`Napi::[Typed]ThreadSafeFunction::New()` creates a persistent reference that
|
|
20
|
+
holds a JavaScript function which can be called from multiple threads. The calls
|
|
21
|
+
happen asynchronously. This means that values with which the JavaScript callback
|
|
22
|
+
is to be called will be placed in a queue, and, for each value in the queue, a
|
|
23
|
+
call will eventually be made to the JavaScript function.
|
|
24
|
+
|
|
25
|
+
`Napi::[Typed]ThreadSafeFunction` objects are destroyed when every thread which
|
|
26
|
+
uses the object has called `Release()` or has received a return status of
|
|
27
|
+
`napi_closing` in response to a call to `BlockingCall()` or `NonBlockingCall()`.
|
|
28
|
+
The queue is emptied before the `Napi::[Typed]ThreadSafeFunction` is destroyed.
|
|
29
|
+
It is important that `Release()` be the last API call made in conjunction with a
|
|
30
|
+
given `Napi::[Typed]ThreadSafeFunction`, because after the call completes, there
|
|
31
|
+
is no guarantee that the `Napi::[Typed]ThreadSafeFunction` is still allocated.
|
|
32
|
+
For the same reason it is also important that no more use be made of a
|
|
33
|
+
thread-safe function after receiving a return value of `napi_closing` in
|
|
34
|
+
response to a call to `BlockingCall()` or `NonBlockingCall()`. Data associated
|
|
35
|
+
with the `Napi::[Typed]ThreadSafeFunction` can be freed in its `Finalizer`
|
|
36
|
+
callback which was passed to `[Typed]ThreadSafeFunction::New()`.
|
|
37
|
+
|
|
38
|
+
Once the number of threads making use of a `Napi::[Typed]ThreadSafeFunction`
|
|
39
|
+
reaches zero, no further threads can start making use of it by calling
|
|
40
|
+
`Acquire()`. In fact, all subsequent API calls associated with it, except
|
|
41
|
+
`Release()`, will return an error value of `napi_closing`.
|
|
42
|
+
|
|
43
|
+
## Implementation Differences
|
|
44
|
+
|
|
45
|
+
The choice between `Napi::ThreadSafeFunction` and
|
|
46
|
+
`Napi::TypedThreadSafeFunction` depends largely on how you plan to execute your
|
|
47
|
+
native C++ code (the "callback") on the Node.js thread.
|
|
48
|
+
|
|
49
|
+
### [`Napi::ThreadSafeFunction`](threadsafe_function.md)
|
|
50
|
+
|
|
51
|
+
This API is designed without N-API 5 native support for [the optional JavaScript
|
|
52
|
+
function callback feature](https://github.com/nodejs/node/commit/53297e66cb).
|
|
53
|
+
|
|
54
|
+
This API has some dynamic functionality, in that:
|
|
55
|
+
- The `[Non]BlockingCall()` methods provide a `Napi::Function` parameter as the
|
|
56
|
+
callback to run when processing the data item on the main thread -- the
|
|
57
|
+
`CallJs` callback. Since the callback is a parameter, it can be changed for
|
|
58
|
+
every call.
|
|
59
|
+
- Different C++ data types may be passed with each call of `[Non]BlockingCall()`
|
|
60
|
+
to match the specific data type as specified in the `CallJs` callback.
|
|
61
|
+
|
|
62
|
+
Note that this functionality comes with some **additional overhead** and
|
|
63
|
+
situational **memory leaks**:
|
|
64
|
+
- The API acts as a "broker" between the underlying `napi_threadsafe_function`,
|
|
65
|
+
and dynamically constructs a wrapper for your callback on the heap for every
|
|
66
|
+
call to `[Non]BlockingCall()`.
|
|
67
|
+
- In acting in this "broker" fashion, the API will call the underlying "make
|
|
68
|
+
call" N-API method on this packaged item. If the API has determined the
|
|
69
|
+
thread-safe function is no longer accessible (eg. all threads have released
|
|
70
|
+
yet there are still items on the queue), **the callback passed to
|
|
71
|
+
[Non]BlockingCall will not execute**. This means it is impossible to perform
|
|
72
|
+
clean-up for calls that never execute their `CallJs` callback. **This may lead
|
|
73
|
+
to memory leaks** if you are dynamically allocating memory.
|
|
74
|
+
- The `CallJs` does not receive the thread-safe function's context as a
|
|
75
|
+
parameter. In order for the callback to access the context, it must have a
|
|
76
|
+
reference to either (1) the context directly, or (2) the thread-safe function
|
|
77
|
+
to call `GetContext()`. Furthermore, the `GetContext()` method is not
|
|
78
|
+
_type-safe_, as the method returns an object that can be "any-casted", instead
|
|
79
|
+
of having a static type.
|
|
80
|
+
|
|
81
|
+
### [`Napi::TypedThreadSafeFunction`](typed_threadsafe_function.md)
|
|
82
|
+
|
|
83
|
+
The `TypedThreadSafeFunction` class is a new implementation to address the
|
|
84
|
+
drawbacks listed above. The API is designed with N-API 5's support of an
|
|
85
|
+
optional function callback. The API will correctly allow developers to pass
|
|
86
|
+
`std::nullptr` instead of a `const Function&` for the callback function
|
|
87
|
+
specified in `::New`. It also provides helper APIs to _target_ N-API 4 and
|
|
88
|
+
construct a no-op `Function` **or** to target N-API 5 and "construct" a
|
|
89
|
+
`std::nullptr` callback. This allows a single codebase to use the same APIs,
|
|
90
|
+
with just a switch of the `NAPI_VERSION` compile-time constant.
|
|
91
|
+
|
|
92
|
+
The removal of the dynamic call functionality has the following implications:
|
|
93
|
+
- The API does _not_ act as a "broker" compared to the
|
|
94
|
+
`Napi::ThreadSafeFunction`. Once Node.js finalizes the thread-safe function,
|
|
95
|
+
the `CallJs` callback will execute with an empty `Napi::Env` for any remaining
|
|
96
|
+
items on the queue. This provides the ability to handle any necessary cleanup
|
|
97
|
+
of the item's data.
|
|
98
|
+
- The callback _does_ receive the context as a parameter, so a call to
|
|
99
|
+
`GetContext()` is _not_ necessary. This context type is specified as the
|
|
100
|
+
**first template argument** specified to `::New`, ensuring type safety.
|
|
101
|
+
- The `New()` constructor accepts the `CallJs` callback as the **second type
|
|
102
|
+
argument**. The callback must be statically defined for the API to access it.
|
|
103
|
+
This affords the ability to statically pass the context as the correct type
|
|
104
|
+
across all methods.
|
|
105
|
+
- Only one C++ data type may be specified to every call to `[Non]BlockingCall()`
|
|
106
|
+
-- the **third template argument** specified to `::New`. Any "dynamic call
|
|
107
|
+
data" must be implemented by the user.
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
### Usage Suggestions
|
|
111
|
+
|
|
112
|
+
In summary, it may be best to use `Napi::TypedThreadSafeFunction` if:
|
|
113
|
+
|
|
114
|
+
- static, compile-time support for targeting N-API 4 or 5+ with an optional
|
|
115
|
+
JavaScript callback feature is desired;
|
|
116
|
+
- the callback can have `static` storage class and will not change across calls
|
|
117
|
+
to `[Non]BlockingCall()`;
|
|
118
|
+
- cleanup of items' data is required (eg. deleting dynamically-allocated data
|
|
119
|
+
that is created at the caller level).
|
|
120
|
+
|
|
121
|
+
Otherwise, `Napi::ThreadSafeFunction` may be a better choice.
|
|
@@ -1,41 +1,10 @@
|
|
|
1
1
|
# ThreadSafeFunction
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
When an addon has additional threads and JavaScript functions need to be invoked
|
|
9
|
-
based on the processing completed by those threads, those threads must
|
|
10
|
-
communicate with the addon's main thread so that the main thread can invoke the
|
|
11
|
-
JavaScript function on their behalf. The thread-safe function APIs provide an
|
|
12
|
-
easy way to do this.
|
|
13
|
-
|
|
14
|
-
These APIs provide the type `Napi::ThreadSafeFunction` as well as APIs to
|
|
15
|
-
create, destroy, and call objects of this type.
|
|
16
|
-
`Napi::ThreadSafeFunction::New()` creates a persistent reference that holds a
|
|
17
|
-
JavaScript function which can be called from multiple threads. The calls happen
|
|
18
|
-
asynchronously. This means that values with which the JavaScript callback is to
|
|
19
|
-
be called will be placed in a queue, and, for each value in the queue, a call
|
|
20
|
-
will eventually be made to the JavaScript function.
|
|
21
|
-
|
|
22
|
-
`Napi::ThreadSafeFunction` objects are destroyed when every thread which uses
|
|
23
|
-
the object has called `Release()` or has received a return status of
|
|
24
|
-
`napi_closing` in response to a call to `BlockingCall()` or `NonBlockingCall()`.
|
|
25
|
-
The queue is emptied before the `Napi::ThreadSafeFunction` is destroyed. It is
|
|
26
|
-
important that `Release()` be the last API call made in conjunction with a given
|
|
27
|
-
`Napi::ThreadSafeFunction`, because after the call completes, there is no
|
|
28
|
-
guarantee that the `Napi::ThreadSafeFunction` is still allocated. For the same
|
|
29
|
-
reason it is also important that no more use be made of a thread-safe function
|
|
30
|
-
after receiving a return value of `napi_closing` in response to a call to
|
|
31
|
-
`BlockingCall()` or `NonBlockingCall()`. Data associated with the
|
|
32
|
-
`Napi::ThreadSafeFunction` can be freed in its `Finalizer` callback which was
|
|
33
|
-
passed to `ThreadSafeFunction::New()`.
|
|
34
|
-
|
|
35
|
-
Once the number of threads making use of a `Napi::ThreadSafeFunction` reaches
|
|
36
|
-
zero, no further threads can start making use of it by calling `Acquire()`. In
|
|
37
|
-
fact, all subsequent API calls associated with it, except `Release()`, will
|
|
38
|
-
return an error value of `napi_closing`.
|
|
3
|
+
The `Napi::ThreadSafeFunction` type provides APIs for threads to communicate
|
|
4
|
+
with the addon's main thread to invoke JavaScript functions on their behalf.
|
|
5
|
+
Documentation can be found for an [overview of the API](threadsafe.md), as well
|
|
6
|
+
as [differences between the two thread-safe function
|
|
7
|
+
APIs](threadsafe.md#implementation-differences).
|
|
39
8
|
|
|
40
9
|
## Methods
|
|
41
10
|
|
|
@@ -92,7 +61,8 @@ New(napi_env env,
|
|
|
92
61
|
- `maxQueueSize`: Maximum size of the queue. `0` for no limit.
|
|
93
62
|
- `initialThreadCount`: The initial number of threads, including the main
|
|
94
63
|
thread, which will be making use of this function.
|
|
95
|
-
- `[optional] context`: Data to attach to the resulting `ThreadSafeFunction`.
|
|
64
|
+
- `[optional] context`: Data to attach to the resulting `ThreadSafeFunction`. It
|
|
65
|
+
can be retreived by calling `GetContext()`.
|
|
96
66
|
- `[optional] finalizeCallback`: Function to call when the `ThreadSafeFunction`
|
|
97
67
|
is being destroyed. This callback will be invoked on the main thread when the
|
|
98
68
|
thread-safe function is about to be destroyed. It receives the context and the
|
|
@@ -101,8 +71,8 @@ New(napi_env env,
|
|
|
101
71
|
`uv_thread_join()`. It is important that, aside from the main loop thread,
|
|
102
72
|
there be no threads left using the thread-safe function after the finalize
|
|
103
73
|
callback completes. Must implement `void operator()(Env env, DataType* data,
|
|
104
|
-
|
|
105
|
-
|
|
74
|
+
ContextType* hint)`, skipping `data` or `hint` if they are not provided. Can
|
|
75
|
+
be retrieved via `GetContext()`.
|
|
106
76
|
- `[optional] data`: Data to be passed to `finalizeCallback`.
|
|
107
77
|
|
|
108
78
|
Returns a non-empty `Napi::ThreadSafeFunction` instance.
|
|
@@ -110,7 +80,7 @@ Returns a non-empty `Napi::ThreadSafeFunction` instance.
|
|
|
110
80
|
### Acquire
|
|
111
81
|
|
|
112
82
|
Add a thread to this thread-safe function object, indicating that a new thread
|
|
113
|
-
will start making use of the thread-safe function.
|
|
83
|
+
will start making use of the thread-safe function.
|
|
114
84
|
|
|
115
85
|
```cpp
|
|
116
86
|
napi_status Napi::ThreadSafeFunction::Acquire()
|
|
@@ -118,7 +88,7 @@ napi_status Napi::ThreadSafeFunction::Acquire()
|
|
|
118
88
|
|
|
119
89
|
Returns one of:
|
|
120
90
|
- `napi_ok`: The thread has successfully acquired the thread-safe function
|
|
121
|
-
for its use.
|
|
91
|
+
for its use.
|
|
122
92
|
- `napi_closing`: The thread-safe function has been marked as closing via a
|
|
123
93
|
previous call to `Abort()`.
|
|
124
94
|
|
|
@@ -136,7 +106,7 @@ napi_status Napi::ThreadSafeFunction::Release()
|
|
|
136
106
|
Returns one of:
|
|
137
107
|
- `napi_ok`: The thread-safe function has been successfully released.
|
|
138
108
|
- `napi_invalid_arg`: The thread-safe function's thread-count is zero.
|
|
139
|
-
- `napi_generic_failure`: A generic error occurred when
|
|
109
|
+
- `napi_generic_failure`: A generic error occurred when attempting to release
|
|
140
110
|
the thread-safe function.
|
|
141
111
|
|
|
142
112
|
### Abort
|
|
@@ -158,7 +128,7 @@ napi_status Napi::ThreadSafeFunction::Abort()
|
|
|
158
128
|
Returns one of:
|
|
159
129
|
- `napi_ok`: The thread-safe function has been successfully aborted.
|
|
160
130
|
- `napi_invalid_arg`: The thread-safe function's thread-count is zero.
|
|
161
|
-
- `napi_generic_failure`: A generic error occurred when
|
|
131
|
+
- `napi_generic_failure`: A generic error occurred when attempting to abort
|
|
162
132
|
the thread-safe function.
|
|
163
133
|
|
|
164
134
|
### BlockingCall / NonBlockingCall
|
|
@@ -210,7 +180,7 @@ Returns one of:
|
|
|
210
180
|
- `napi_closing`: The thread-safe function is aborted and cannot accept more
|
|
211
181
|
calls.
|
|
212
182
|
- `napi_invalid_arg`: The thread-safe function is closed.
|
|
213
|
-
- `napi_generic_failure`: A generic error occurred when
|
|
183
|
+
- `napi_generic_failure`: A generic error occurred when attempting to add to the
|
|
214
184
|
queue.
|
|
215
185
|
|
|
216
186
|
## Example
|
|
@@ -258,10 +228,10 @@ Value Start( const CallbackInfo& info )
|
|
|
258
228
|
// Create a native thread
|
|
259
229
|
nativeThread = std::thread( [count] {
|
|
260
230
|
auto callback = []( Napi::Env env, Function jsCallback, int* value ) {
|
|
261
|
-
// Transform native data into JS data, passing it to the provided
|
|
231
|
+
// Transform native data into JS data, passing it to the provided
|
|
262
232
|
// `jsCallback` -- the TSFN's JavaScript function.
|
|
263
233
|
jsCallback.Call( {Number::New( env, *value )} );
|
|
264
|
-
|
|
234
|
+
|
|
265
235
|
// We're finished with the data.
|
|
266
236
|
delete value;
|
|
267
237
|
};
|
package/doc/typed_array.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# TypedArray
|
|
2
2
|
|
|
3
|
+
Class `Napi::TypedArray` inherits from class [`Napi::Object`][].
|
|
4
|
+
|
|
3
5
|
The `Napi::TypedArray` class corresponds to the
|
|
4
6
|
[JavaScript `TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)
|
|
5
7
|
class.
|
|
@@ -72,3 +74,5 @@ size_t Napi::TypedArray::ByteLength() const;
|
|
|
72
74
|
```
|
|
73
75
|
|
|
74
76
|
Returns the length of the array, in bytes.
|
|
77
|
+
|
|
78
|
+
[`Napi::Object`]: ./object.md
|
package/doc/typed_array_of.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# TypedArrayOf
|
|
2
2
|
|
|
3
|
+
Class `Napi::TypedArrayOf<T>` inherits from class [`Napi::TypedArray`][].
|
|
4
|
+
|
|
3
5
|
The `Napi::TypedArrayOf` class corresponds to the various
|
|
4
6
|
[JavaScript `TypedArray`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)
|
|
5
7
|
classes.
|
|
@@ -131,3 +133,5 @@ const T* Napi::TypedArrayOf::Data() const
|
|
|
131
133
|
|
|
132
134
|
Returns a pointer into the backing `Napi::ArrayBuffer` which is offset to point to the
|
|
133
135
|
start of the array.
|
|
136
|
+
|
|
137
|
+
[`Napi::TypedArray`]: ./typed_array.md
|