node-addon-api 2.0.2 → 3.0.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/.travis.yml +1 -4
- package/CHANGELOG.md +88 -30
- package/README.md +53 -7
- package/benchmark/README.md +47 -0
- package/benchmark/binding.gyp +25 -0
- package/benchmark/function_args.cc +153 -0
- package/benchmark/function_args.js +52 -0
- package/benchmark/index.js +34 -0
- package/benchmark/property_descriptor.cc +60 -0
- package/benchmark/property_descriptor.js +29 -0
- package/common.gypi +21 -0
- package/doc/async_worker.md +33 -4
- package/doc/{async_progress_worker.md → async_worker_variants.md} +115 -3
- package/doc/bigint.md +2 -1
- package/doc/class_property_descriptor.md +3 -3
- package/doc/creating_a_release.md +5 -5
- package/doc/env.md +14 -0
- package/doc/function.md +108 -1
- package/doc/object.md +40 -1
- package/doc/object_lifetime_management.md +1 -1
- package/doc/object_wrap.md +278 -2
- package/doc/property_descriptor.md +64 -9
- package/doc/setup.md +0 -1
- package/doc/string.md +1 -1
- package/doc/symbol.md +1 -1
- package/doc/value.md +1 -1
- package/except.gypi +16 -0
- package/index.js +5 -42
- package/napi-inl.h +727 -141
- package/napi.h +338 -83
- package/node_api.gyp +9 -0
- package/noexcept.gypi +16 -0
- package/{src/nothing.c → nothing.c} +0 -0
- package/package.json +33 -1
- package/tools/README.md +4 -4
- package/tools/conversion.js +0 -4
- 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/napi-inl.h
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
// Note: Do not include this file directly! Include "napi.h" instead.
|
|
11
11
|
|
|
12
12
|
#include <algorithm>
|
|
13
|
-
#include <atomic>
|
|
14
13
|
#include <cstring>
|
|
15
14
|
#include <mutex>
|
|
16
15
|
#include <type_traits>
|
|
@@ -20,8 +19,6 @@ namespace Napi {
|
|
|
20
19
|
// Helpers to handle functions exposed from C++.
|
|
21
20
|
namespace details {
|
|
22
21
|
|
|
23
|
-
extern std::atomic_bool needs_objectwrap_destructor_fix;
|
|
24
|
-
|
|
25
22
|
// Attach a data item to an object and delete it when the object gets
|
|
26
23
|
// garbage-collected.
|
|
27
24
|
// TODO: Replace this code with `napi_add_finalizer()` whenever it becomes
|
|
@@ -153,9 +150,6 @@ struct ThreadSafeFinalize {
|
|
|
153
150
|
ThreadSafeFinalize* finalizeData =
|
|
154
151
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
155
152
|
finalizeData->callback(Env(env));
|
|
156
|
-
if (finalizeData->tsfn) {
|
|
157
|
-
*finalizeData->tsfn = nullptr;
|
|
158
|
-
}
|
|
159
153
|
delete finalizeData;
|
|
160
154
|
}
|
|
161
155
|
|
|
@@ -169,9 +163,6 @@ struct ThreadSafeFinalize {
|
|
|
169
163
|
ThreadSafeFinalize* finalizeData =
|
|
170
164
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
171
165
|
finalizeData->callback(Env(env), finalizeData->data);
|
|
172
|
-
if (finalizeData->tsfn) {
|
|
173
|
-
*finalizeData->tsfn = nullptr;
|
|
174
|
-
}
|
|
175
166
|
delete finalizeData;
|
|
176
167
|
}
|
|
177
168
|
|
|
@@ -185,9 +176,6 @@ struct ThreadSafeFinalize {
|
|
|
185
176
|
ThreadSafeFinalize* finalizeData =
|
|
186
177
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
187
178
|
finalizeData->callback(Env(env), static_cast<ContextType*>(rawContext));
|
|
188
|
-
if (finalizeData->tsfn) {
|
|
189
|
-
*finalizeData->tsfn = nullptr;
|
|
190
|
-
}
|
|
191
179
|
delete finalizeData;
|
|
192
180
|
}
|
|
193
181
|
|
|
@@ -202,15 +190,11 @@ struct ThreadSafeFinalize {
|
|
|
202
190
|
static_cast<ThreadSafeFinalize*>(rawFinalizeData);
|
|
203
191
|
finalizeData->callback(Env(env), finalizeData->data,
|
|
204
192
|
static_cast<ContextType*>(rawContext));
|
|
205
|
-
if (finalizeData->tsfn) {
|
|
206
|
-
*finalizeData->tsfn = nullptr;
|
|
207
|
-
}
|
|
208
193
|
delete finalizeData;
|
|
209
194
|
}
|
|
210
195
|
|
|
211
196
|
FinalizerDataType* data;
|
|
212
197
|
Finalizer callback;
|
|
213
|
-
napi_threadsafe_function* tsfn;
|
|
214
198
|
};
|
|
215
199
|
#endif
|
|
216
200
|
|
|
@@ -254,16 +238,11 @@ struct AccessorCallbackData {
|
|
|
254
238
|
// Module registration
|
|
255
239
|
////////////////////////////////////////////////////////////////////////////////
|
|
256
240
|
|
|
257
|
-
#define NODE_API_MODULE(modname, regfunc)
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
} \
|
|
263
|
-
napi_value __napi_ ## regfunc(napi_env env, \
|
|
264
|
-
napi_value exports) { \
|
|
265
|
-
return Napi::RegisterModule(env, exports, regfunc); \
|
|
266
|
-
} \
|
|
241
|
+
#define NODE_API_MODULE(modname, regfunc) \
|
|
242
|
+
napi_value __napi_ ## regfunc(napi_env env, \
|
|
243
|
+
napi_value exports) { \
|
|
244
|
+
return Napi::RegisterModule(env, exports, regfunc); \
|
|
245
|
+
} \
|
|
267
246
|
NAPI_MODULE(modname, __napi_ ## regfunc)
|
|
268
247
|
|
|
269
248
|
// Adapt the NAPI_MODULE registration function:
|
|
@@ -272,12 +251,6 @@ struct AccessorCallbackData {
|
|
|
272
251
|
inline napi_value RegisterModule(napi_env env,
|
|
273
252
|
napi_value exports,
|
|
274
253
|
ModuleRegisterCallback registerCallback) {
|
|
275
|
-
const napi_node_version* nver = Napi::VersionManagement::GetNodeVersion(env);
|
|
276
|
-
Napi::details::needs_objectwrap_destructor_fix =
|
|
277
|
-
(nver->major < 10 ||
|
|
278
|
-
(nver->major == 10 && nver->minor < 15) ||
|
|
279
|
-
(nver->major == 10 && nver->minor == 15 && nver->patch < 3));
|
|
280
|
-
|
|
281
254
|
return details::WrapCallback([&] {
|
|
282
255
|
return napi_value(registerCallback(Napi::Env(env),
|
|
283
256
|
Napi::Object(env, exports)));
|
|
@@ -333,6 +306,64 @@ inline Error Env::GetAndClearPendingException() {
|
|
|
333
306
|
return Error(_env, value);
|
|
334
307
|
}
|
|
335
308
|
|
|
309
|
+
inline Value Env::RunScript(const char* utf8script) {
|
|
310
|
+
String script = String::New(_env, utf8script);
|
|
311
|
+
return RunScript(script);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
inline Value Env::RunScript(const std::string& utf8script) {
|
|
315
|
+
return RunScript(utf8script.c_str());
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
inline Value Env::RunScript(String script) {
|
|
319
|
+
napi_value result;
|
|
320
|
+
napi_status status = napi_run_script(_env, script, &result);
|
|
321
|
+
NAPI_THROW_IF_FAILED(_env, status, Undefined());
|
|
322
|
+
return Value(_env, result);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
#if NAPI_VERSION > 5
|
|
326
|
+
template <typename T, Env::Finalizer<T> fini>
|
|
327
|
+
inline void Env::SetInstanceData(T* data) {
|
|
328
|
+
napi_status status =
|
|
329
|
+
napi_set_instance_data(_env, data, [](napi_env env, void* data, void*) {
|
|
330
|
+
fini(env, static_cast<T*>(data));
|
|
331
|
+
}, nullptr);
|
|
332
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
template <typename DataType,
|
|
336
|
+
typename HintType,
|
|
337
|
+
Napi::Env::FinalizerWithHint<DataType, HintType> fini>
|
|
338
|
+
inline void Env::SetInstanceData(DataType* data, HintType* hint) {
|
|
339
|
+
napi_status status =
|
|
340
|
+
napi_set_instance_data(_env, data,
|
|
341
|
+
[](napi_env env, void* data, void* hint) {
|
|
342
|
+
fini(env, static_cast<DataType*>(data), static_cast<HintType*>(hint));
|
|
343
|
+
}, hint);
|
|
344
|
+
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
template <typename T>
|
|
348
|
+
inline T* Env::GetInstanceData() {
|
|
349
|
+
void* data = nullptr;
|
|
350
|
+
|
|
351
|
+
napi_status status = napi_get_instance_data(_env, &data);
|
|
352
|
+
NAPI_THROW_IF_FAILED(_env, status, nullptr);
|
|
353
|
+
|
|
354
|
+
return static_cast<T*>(data);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
template <typename T> void Env::DefaultFini(Env, T* data) {
|
|
358
|
+
delete data;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
template <typename DataType, typename HintType>
|
|
362
|
+
void Env::DefaultFiniWithHint(Env, DataType* data, HintType*) {
|
|
363
|
+
delete data;
|
|
364
|
+
}
|
|
365
|
+
#endif // NAPI_VERSION > 5
|
|
366
|
+
|
|
336
367
|
////////////////////////////////////////////////////////////////////////////////
|
|
337
368
|
// Value class
|
|
338
369
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -397,14 +428,11 @@ inline bool Value::IsNumber() const {
|
|
|
397
428
|
return Type() == napi_number;
|
|
398
429
|
}
|
|
399
430
|
|
|
400
|
-
|
|
401
|
-
// Once it is no longer experimental guard with the NAPI_VERSION in which it is
|
|
402
|
-
// released instead.
|
|
403
|
-
#ifdef NAPI_EXPERIMENTAL
|
|
431
|
+
#if NAPI_VERSION > 5
|
|
404
432
|
inline bool Value::IsBigInt() const {
|
|
405
433
|
return Type() == napi_bigint;
|
|
406
434
|
}
|
|
407
|
-
#endif //
|
|
435
|
+
#endif // NAPI_VERSION > 5
|
|
408
436
|
|
|
409
437
|
#if (NAPI_VERSION > 4)
|
|
410
438
|
inline bool Value::IsDate() const {
|
|
@@ -635,10 +663,7 @@ inline double Number::DoubleValue() const {
|
|
|
635
663
|
return result;
|
|
636
664
|
}
|
|
637
665
|
|
|
638
|
-
|
|
639
|
-
// Once it is no longer experimental guard with the NAPI_VERSION in which it is
|
|
640
|
-
// released instead.
|
|
641
|
-
#ifdef NAPI_EXPERIMENTAL
|
|
666
|
+
#if NAPI_VERSION > 5
|
|
642
667
|
////////////////////////////////////////////////////////////////////////////////
|
|
643
668
|
// BigInt Class
|
|
644
669
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -699,7 +724,7 @@ inline void BigInt::ToWords(int* sign_bit, size_t* word_count, uint64_t* words)
|
|
|
699
724
|
_env, _value, sign_bit, word_count, words);
|
|
700
725
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
701
726
|
}
|
|
702
|
-
#endif //
|
|
727
|
+
#endif // NAPI_VERSION > 5
|
|
703
728
|
|
|
704
729
|
#if (NAPI_VERSION > 4)
|
|
705
730
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -1344,7 +1369,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env, size_t byteLength) {
|
|
|
1344
1369
|
napi_status status = napi_create_arraybuffer(env, byteLength, &data, &value);
|
|
1345
1370
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1346
1371
|
|
|
1347
|
-
return ArrayBuffer(env, value
|
|
1372
|
+
return ArrayBuffer(env, value);
|
|
1348
1373
|
}
|
|
1349
1374
|
|
|
1350
1375
|
inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
@@ -1355,7 +1380,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1355
1380
|
env, externalData, byteLength, nullptr, nullptr, &value);
|
|
1356
1381
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1357
1382
|
|
|
1358
|
-
return ArrayBuffer(env, value
|
|
1383
|
+
return ArrayBuffer(env, value);
|
|
1359
1384
|
}
|
|
1360
1385
|
|
|
1361
1386
|
template <typename Finalizer>
|
|
@@ -1378,7 +1403,7 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1378
1403
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1379
1404
|
}
|
|
1380
1405
|
|
|
1381
|
-
return ArrayBuffer(env, value
|
|
1406
|
+
return ArrayBuffer(env, value);
|
|
1382
1407
|
}
|
|
1383
1408
|
|
|
1384
1409
|
template <typename Finalizer, typename Hint>
|
|
@@ -1402,38 +1427,28 @@ inline ArrayBuffer ArrayBuffer::New(napi_env env,
|
|
|
1402
1427
|
NAPI_THROW_IF_FAILED(env, status, ArrayBuffer());
|
|
1403
1428
|
}
|
|
1404
1429
|
|
|
1405
|
-
return ArrayBuffer(env, value
|
|
1430
|
+
return ArrayBuffer(env, value);
|
|
1406
1431
|
}
|
|
1407
1432
|
|
|
1408
|
-
inline ArrayBuffer::ArrayBuffer() : Object()
|
|
1433
|
+
inline ArrayBuffer::ArrayBuffer() : Object() {
|
|
1409
1434
|
}
|
|
1410
1435
|
|
|
1411
1436
|
inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value)
|
|
1412
|
-
: Object(env, value)
|
|
1413
|
-
}
|
|
1414
|
-
|
|
1415
|
-
inline ArrayBuffer::ArrayBuffer(napi_env env, napi_value value, void* data, size_t length)
|
|
1416
|
-
: Object(env, value), _data(data), _length(length) {
|
|
1437
|
+
: Object(env, value) {
|
|
1417
1438
|
}
|
|
1418
1439
|
|
|
1419
1440
|
inline void* ArrayBuffer::Data() {
|
|
1420
|
-
|
|
1421
|
-
|
|
1441
|
+
void* data;
|
|
1442
|
+
napi_status status = napi_get_arraybuffer_info(_env, _value, &data, nullptr);
|
|
1443
|
+
NAPI_THROW_IF_FAILED(_env, status, nullptr);
|
|
1444
|
+
return data;
|
|
1422
1445
|
}
|
|
1423
1446
|
|
|
1424
1447
|
inline size_t ArrayBuffer::ByteLength() {
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
inline void ArrayBuffer::EnsureInfo() const {
|
|
1430
|
-
// The ArrayBuffer instance may have been constructed from a napi_value whose
|
|
1431
|
-
// length/data are not yet known. Fetch and cache these values just once,
|
|
1432
|
-
// since they can never change during the lifetime of the ArrayBuffer.
|
|
1433
|
-
if (_data == nullptr) {
|
|
1434
|
-
napi_status status = napi_get_arraybuffer_info(_env, _value, &_data, &_length);
|
|
1435
|
-
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
1436
|
-
}
|
|
1448
|
+
size_t length;
|
|
1449
|
+
napi_status status = napi_get_arraybuffer_info(_env, _value, nullptr, &length);
|
|
1450
|
+
NAPI_THROW_IF_FAILED(_env, status, 0);
|
|
1451
|
+
return length;
|
|
1437
1452
|
}
|
|
1438
1453
|
|
|
1439
1454
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -1649,6 +1664,10 @@ inline uint8_t TypedArray::ElementSize() const {
|
|
|
1649
1664
|
case napi_float32_array:
|
|
1650
1665
|
return 4;
|
|
1651
1666
|
case napi_float64_array:
|
|
1667
|
+
#if (NAPI_VERSION > 5)
|
|
1668
|
+
case napi_bigint64_array:
|
|
1669
|
+
case napi_biguint64_array:
|
|
1670
|
+
#endif // (NAPI_VERSION > 5)
|
|
1652
1671
|
return 8;
|
|
1653
1672
|
default:
|
|
1654
1673
|
return 0;
|
|
@@ -1780,6 +1799,51 @@ CreateFunction(napi_env env,
|
|
|
1780
1799
|
return status;
|
|
1781
1800
|
}
|
|
1782
1801
|
|
|
1802
|
+
template <Function::VoidCallback cb>
|
|
1803
|
+
inline Function Function::New(napi_env env, const char* utf8name, void* data) {
|
|
1804
|
+
napi_value result = nullptr;
|
|
1805
|
+
napi_status status = napi_create_function(
|
|
1806
|
+
env, utf8name, NAPI_AUTO_LENGTH,
|
|
1807
|
+
[](napi_env env, napi_callback_info info) {
|
|
1808
|
+
CallbackInfo callbackInfo(env, info);
|
|
1809
|
+
return details::WrapCallback([&] {
|
|
1810
|
+
cb(callbackInfo);
|
|
1811
|
+
return nullptr;
|
|
1812
|
+
});
|
|
1813
|
+
}, data, &result);
|
|
1814
|
+
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
1815
|
+
return Function(env, result);
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
template <Function::Callback cb>
|
|
1819
|
+
inline Function Function::New(napi_env env, const char* utf8name, void* data) {
|
|
1820
|
+
napi_value result = nullptr;
|
|
1821
|
+
napi_status status = napi_create_function(
|
|
1822
|
+
env, utf8name, NAPI_AUTO_LENGTH,
|
|
1823
|
+
[](napi_env env, napi_callback_info info) {
|
|
1824
|
+
CallbackInfo callbackInfo(env, info);
|
|
1825
|
+
return details::WrapCallback([&] {
|
|
1826
|
+
return cb(callbackInfo);
|
|
1827
|
+
});
|
|
1828
|
+
}, data, &result);
|
|
1829
|
+
NAPI_THROW_IF_FAILED(env, status, Function());
|
|
1830
|
+
return Function(env, result);
|
|
1831
|
+
}
|
|
1832
|
+
|
|
1833
|
+
template <Function::VoidCallback cb>
|
|
1834
|
+
inline Function Function::New(napi_env env,
|
|
1835
|
+
const std::string& utf8name,
|
|
1836
|
+
void* data) {
|
|
1837
|
+
return Function::New<cb>(env, utf8name.c_str(), data);
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1840
|
+
template <Function::Callback cb>
|
|
1841
|
+
inline Function Function::New(napi_env env,
|
|
1842
|
+
const std::string& utf8name,
|
|
1843
|
+
void* data) {
|
|
1844
|
+
return Function::New<cb>(env, utf8name.c_str(), data);
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1783
1847
|
template <typename Callable>
|
|
1784
1848
|
inline Function Function::New(napi_env env,
|
|
1785
1849
|
Callable cb,
|
|
@@ -2051,12 +2115,19 @@ inline void Buffer<T>::EnsureInfo() const {
|
|
|
2051
2115
|
inline Error Error::New(napi_env env) {
|
|
2052
2116
|
napi_status status;
|
|
2053
2117
|
napi_value error = nullptr;
|
|
2054
|
-
|
|
2118
|
+
bool is_exception_pending;
|
|
2055
2119
|
const napi_extended_error_info* info;
|
|
2120
|
+
|
|
2121
|
+
// We must retrieve the last error info before doing anything else, because
|
|
2122
|
+
// doing anything else will replace the last error info.
|
|
2056
2123
|
status = napi_get_last_error_info(env, &info);
|
|
2057
2124
|
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_last_error_info");
|
|
2058
2125
|
|
|
2059
|
-
|
|
2126
|
+
status = napi_is_exception_pending(env, &is_exception_pending);
|
|
2127
|
+
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
|
|
2128
|
+
|
|
2129
|
+
// A pending exception takes precedence over any internal error status.
|
|
2130
|
+
if (is_exception_pending) {
|
|
2060
2131
|
status = napi_get_and_clear_last_exception(env, &error);
|
|
2061
2132
|
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
|
|
2062
2133
|
}
|
|
@@ -2064,15 +2135,6 @@ inline Error Error::New(napi_env env) {
|
|
|
2064
2135
|
const char* error_message = info->error_message != nullptr ?
|
|
2065
2136
|
info->error_message : "Error in native callback";
|
|
2066
2137
|
|
|
2067
|
-
bool isExceptionPending;
|
|
2068
|
-
status = napi_is_exception_pending(env, &isExceptionPending);
|
|
2069
|
-
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_is_exception_pending");
|
|
2070
|
-
|
|
2071
|
-
if (isExceptionPending) {
|
|
2072
|
-
status = napi_get_and_clear_last_exception(env, &error);
|
|
2073
|
-
NAPI_FATAL_IF_FAILED(status, "Error::New", "napi_get_and_clear_last_exception");
|
|
2074
|
-
}
|
|
2075
|
-
|
|
2076
2138
|
napi_value message;
|
|
2077
2139
|
status = napi_create_string_utf8(
|
|
2078
2140
|
env,
|
|
@@ -2134,7 +2196,7 @@ inline Error& Error::operator =(Error&& other) {
|
|
|
2134
2196
|
inline Error::Error(const Error& other) : ObjectReference(other) {
|
|
2135
2197
|
}
|
|
2136
2198
|
|
|
2137
|
-
inline Error& Error::operator =(Error& other) {
|
|
2199
|
+
inline Error& Error::operator =(const Error& other) {
|
|
2138
2200
|
Reset();
|
|
2139
2201
|
|
|
2140
2202
|
_env = other.Env();
|
|
@@ -2746,6 +2808,108 @@ inline void CallbackInfo::SetData(void* data) {
|
|
|
2746
2808
|
// PropertyDescriptor class
|
|
2747
2809
|
////////////////////////////////////////////////////////////////////////////////
|
|
2748
2810
|
|
|
2811
|
+
template <typename PropertyDescriptor::GetterCallback Getter>
|
|
2812
|
+
PropertyDescriptor
|
|
2813
|
+
PropertyDescriptor::Accessor(const char* utf8name,
|
|
2814
|
+
napi_property_attributes attributes,
|
|
2815
|
+
void* data) {
|
|
2816
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
2817
|
+
|
|
2818
|
+
desc.utf8name = utf8name;
|
|
2819
|
+
desc.getter = &GetterCallbackWrapper<Getter>;
|
|
2820
|
+
desc.attributes = attributes;
|
|
2821
|
+
desc.data = data;
|
|
2822
|
+
|
|
2823
|
+
return desc;
|
|
2824
|
+
}
|
|
2825
|
+
|
|
2826
|
+
template <typename PropertyDescriptor::GetterCallback Getter>
|
|
2827
|
+
PropertyDescriptor
|
|
2828
|
+
PropertyDescriptor::Accessor(const std::string& utf8name,
|
|
2829
|
+
napi_property_attributes attributes,
|
|
2830
|
+
void* data) {
|
|
2831
|
+
return Accessor<Getter>(utf8name.c_str(), attributes, data);
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
template <typename PropertyDescriptor::GetterCallback Getter>
|
|
2835
|
+
PropertyDescriptor
|
|
2836
|
+
PropertyDescriptor::Accessor(Name name,
|
|
2837
|
+
napi_property_attributes attributes,
|
|
2838
|
+
void* data) {
|
|
2839
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
2840
|
+
|
|
2841
|
+
desc.name = name;
|
|
2842
|
+
desc.getter = &GetterCallbackWrapper<Getter>;
|
|
2843
|
+
desc.attributes = attributes;
|
|
2844
|
+
desc.data = data;
|
|
2845
|
+
|
|
2846
|
+
return desc;
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
template <
|
|
2850
|
+
typename PropertyDescriptor::GetterCallback Getter,
|
|
2851
|
+
typename PropertyDescriptor::SetterCallback Setter>
|
|
2852
|
+
PropertyDescriptor
|
|
2853
|
+
PropertyDescriptor::Accessor(const char* utf8name,
|
|
2854
|
+
napi_property_attributes attributes,
|
|
2855
|
+
void* data) {
|
|
2856
|
+
|
|
2857
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
2858
|
+
|
|
2859
|
+
desc.utf8name = utf8name;
|
|
2860
|
+
desc.getter = &GetterCallbackWrapper<Getter>;
|
|
2861
|
+
desc.setter = &SetterCallbackWrapper<Setter>;
|
|
2862
|
+
desc.attributes = attributes;
|
|
2863
|
+
desc.data = data;
|
|
2864
|
+
|
|
2865
|
+
return desc;
|
|
2866
|
+
}
|
|
2867
|
+
|
|
2868
|
+
template <
|
|
2869
|
+
typename PropertyDescriptor::GetterCallback Getter,
|
|
2870
|
+
typename PropertyDescriptor::SetterCallback Setter>
|
|
2871
|
+
PropertyDescriptor
|
|
2872
|
+
PropertyDescriptor::Accessor(const std::string& utf8name,
|
|
2873
|
+
napi_property_attributes attributes,
|
|
2874
|
+
void* data) {
|
|
2875
|
+
return Accessor<Getter, Setter>(utf8name.c_str(), attributes, data);
|
|
2876
|
+
}
|
|
2877
|
+
|
|
2878
|
+
template <
|
|
2879
|
+
typename PropertyDescriptor::GetterCallback Getter,
|
|
2880
|
+
typename PropertyDescriptor::SetterCallback Setter>
|
|
2881
|
+
PropertyDescriptor
|
|
2882
|
+
PropertyDescriptor::Accessor(Name name,
|
|
2883
|
+
napi_property_attributes attributes,
|
|
2884
|
+
void* data) {
|
|
2885
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
2886
|
+
|
|
2887
|
+
desc.name = name;
|
|
2888
|
+
desc.getter = &GetterCallbackWrapper<Getter>;
|
|
2889
|
+
desc.setter = &SetterCallbackWrapper<Setter>;
|
|
2890
|
+
desc.attributes = attributes;
|
|
2891
|
+
desc.data = data;
|
|
2892
|
+
|
|
2893
|
+
return desc;
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2896
|
+
template <typename PropertyDescriptor::GetterCallback Getter>
|
|
2897
|
+
napi_value
|
|
2898
|
+
PropertyDescriptor::GetterCallbackWrapper(napi_env env,
|
|
2899
|
+
napi_callback_info info) {
|
|
2900
|
+
CallbackInfo cbInfo(env, info);
|
|
2901
|
+
return Getter(cbInfo);
|
|
2902
|
+
}
|
|
2903
|
+
|
|
2904
|
+
template <typename PropertyDescriptor::SetterCallback Setter>
|
|
2905
|
+
napi_value
|
|
2906
|
+
PropertyDescriptor::SetterCallbackWrapper(napi_env env,
|
|
2907
|
+
napi_callback_info info) {
|
|
2908
|
+
CallbackInfo cbInfo(env, info);
|
|
2909
|
+
Setter(cbInfo);
|
|
2910
|
+
return nullptr;
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2749
2913
|
template <typename Getter>
|
|
2750
2914
|
inline PropertyDescriptor
|
|
2751
2915
|
PropertyDescriptor::Accessor(Napi::Env env,
|
|
@@ -2999,16 +3163,6 @@ inline ObjectWrap<T>::~ObjectWrap() {
|
|
|
2999
3163
|
// This happens e.g. during garbage collection.
|
|
3000
3164
|
if (!object.IsEmpty() && _construction_failed) {
|
|
3001
3165
|
napi_remove_wrap(Env(), object, nullptr);
|
|
3002
|
-
|
|
3003
|
-
if (Napi::details::needs_objectwrap_destructor_fix) {
|
|
3004
|
-
// If construction failed we delete the reference via
|
|
3005
|
-
// `napi_remove_wrap()`, not via `napi_delete_reference()` in the
|
|
3006
|
-
// `Reference<Object>` destructor. This will prevent the
|
|
3007
|
-
// `Reference<Object>` destructor from doing a double delete of this
|
|
3008
|
-
// reference.
|
|
3009
|
-
_ref = nullptr;
|
|
3010
|
-
_env = nullptr;
|
|
3011
|
-
}
|
|
3012
3166
|
}
|
|
3013
3167
|
}
|
|
3014
3168
|
}
|
|
@@ -3200,6 +3354,62 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
|
3200
3354
|
return desc;
|
|
3201
3355
|
}
|
|
3202
3356
|
|
|
3357
|
+
template <typename T>
|
|
3358
|
+
template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
|
|
3359
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3360
|
+
const char* utf8name,
|
|
3361
|
+
napi_property_attributes attributes,
|
|
3362
|
+
void* data) {
|
|
3363
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3364
|
+
desc.utf8name = utf8name;
|
|
3365
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3366
|
+
desc.data = data;
|
|
3367
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3368
|
+
return desc;
|
|
3369
|
+
}
|
|
3370
|
+
|
|
3371
|
+
template <typename T>
|
|
3372
|
+
template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
|
|
3373
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3374
|
+
Symbol name,
|
|
3375
|
+
napi_property_attributes attributes,
|
|
3376
|
+
void* data) {
|
|
3377
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3378
|
+
desc.name = name;
|
|
3379
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3380
|
+
desc.data = data;
|
|
3381
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3382
|
+
return desc;
|
|
3383
|
+
}
|
|
3384
|
+
|
|
3385
|
+
template <typename T>
|
|
3386
|
+
template <typename ObjectWrap<T>::StaticMethodCallback method>
|
|
3387
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3388
|
+
const char* utf8name,
|
|
3389
|
+
napi_property_attributes attributes,
|
|
3390
|
+
void* data) {
|
|
3391
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3392
|
+
desc.utf8name = utf8name;
|
|
3393
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3394
|
+
desc.data = data;
|
|
3395
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3396
|
+
return desc;
|
|
3397
|
+
}
|
|
3398
|
+
|
|
3399
|
+
template <typename T>
|
|
3400
|
+
template <typename ObjectWrap<T>::StaticMethodCallback method>
|
|
3401
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticMethod(
|
|
3402
|
+
Symbol name,
|
|
3403
|
+
napi_property_attributes attributes,
|
|
3404
|
+
void* data) {
|
|
3405
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3406
|
+
desc.name = name;
|
|
3407
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3408
|
+
desc.data = data;
|
|
3409
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3410
|
+
return desc;
|
|
3411
|
+
}
|
|
3412
|
+
|
|
3203
3413
|
template <typename T>
|
|
3204
3414
|
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
3205
3415
|
const char* utf8name,
|
|
@@ -3238,6 +3448,38 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
|
3238
3448
|
return desc;
|
|
3239
3449
|
}
|
|
3240
3450
|
|
|
3451
|
+
template <typename T>
|
|
3452
|
+
template <typename ObjectWrap<T>::StaticGetterCallback getter,
|
|
3453
|
+
typename ObjectWrap<T>::StaticSetterCallback setter>
|
|
3454
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
3455
|
+
const char* utf8name,
|
|
3456
|
+
napi_property_attributes attributes,
|
|
3457
|
+
void* data) {
|
|
3458
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3459
|
+
desc.utf8name = utf8name;
|
|
3460
|
+
desc.getter = This::WrapStaticGetter(This::StaticGetterTag<getter>());
|
|
3461
|
+
desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
|
|
3462
|
+
desc.data = data;
|
|
3463
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3464
|
+
return desc;
|
|
3465
|
+
}
|
|
3466
|
+
|
|
3467
|
+
template <typename T>
|
|
3468
|
+
template <typename ObjectWrap<T>::StaticGetterCallback getter,
|
|
3469
|
+
typename ObjectWrap<T>::StaticSetterCallback setter>
|
|
3470
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticAccessor(
|
|
3471
|
+
Symbol name,
|
|
3472
|
+
napi_property_attributes attributes,
|
|
3473
|
+
void* data) {
|
|
3474
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3475
|
+
desc.name = name;
|
|
3476
|
+
desc.getter = This::WrapStaticGetter(This::StaticGetterTag<getter>());
|
|
3477
|
+
desc.setter = This::WrapStaticSetter(This::StaticSetterTag<setter>());
|
|
3478
|
+
desc.data = data;
|
|
3479
|
+
desc.attributes = static_cast<napi_property_attributes>(attributes | napi_static);
|
|
3480
|
+
return desc;
|
|
3481
|
+
}
|
|
3482
|
+
|
|
3241
3483
|
template <typename T>
|
|
3242
3484
|
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
3243
3485
|
const char* utf8name,
|
|
@@ -3304,6 +3546,62 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
|
3304
3546
|
return desc;
|
|
3305
3547
|
}
|
|
3306
3548
|
|
|
3549
|
+
template <typename T>
|
|
3550
|
+
template <typename ObjectWrap<T>::InstanceVoidMethodCallback method>
|
|
3551
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
3552
|
+
const char* utf8name,
|
|
3553
|
+
napi_property_attributes attributes,
|
|
3554
|
+
void* data) {
|
|
3555
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3556
|
+
desc.utf8name = utf8name;
|
|
3557
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3558
|
+
desc.data = data;
|
|
3559
|
+
desc.attributes = attributes;
|
|
3560
|
+
return desc;
|
|
3561
|
+
}
|
|
3562
|
+
|
|
3563
|
+
template <typename T>
|
|
3564
|
+
template <typename ObjectWrap<T>::InstanceMethodCallback method>
|
|
3565
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
3566
|
+
const char* utf8name,
|
|
3567
|
+
napi_property_attributes attributes,
|
|
3568
|
+
void* data) {
|
|
3569
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3570
|
+
desc.utf8name = utf8name;
|
|
3571
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3572
|
+
desc.data = data;
|
|
3573
|
+
desc.attributes = attributes;
|
|
3574
|
+
return desc;
|
|
3575
|
+
}
|
|
3576
|
+
|
|
3577
|
+
template <typename T>
|
|
3578
|
+
template <typename ObjectWrap<T>::InstanceVoidMethodCallback method>
|
|
3579
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
3580
|
+
Symbol name,
|
|
3581
|
+
napi_property_attributes attributes,
|
|
3582
|
+
void* data) {
|
|
3583
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3584
|
+
desc.name = name;
|
|
3585
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3586
|
+
desc.data = data;
|
|
3587
|
+
desc.attributes = attributes;
|
|
3588
|
+
return desc;
|
|
3589
|
+
}
|
|
3590
|
+
|
|
3591
|
+
template <typename T>
|
|
3592
|
+
template <typename ObjectWrap<T>::InstanceMethodCallback method>
|
|
3593
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceMethod(
|
|
3594
|
+
Symbol name,
|
|
3595
|
+
napi_property_attributes attributes,
|
|
3596
|
+
void* data) {
|
|
3597
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3598
|
+
desc.name = name;
|
|
3599
|
+
desc.method = &ObjectWrap<T>::WrappedMethod<method>;
|
|
3600
|
+
desc.data = data;
|
|
3601
|
+
desc.attributes = attributes;
|
|
3602
|
+
return desc;
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3307
3605
|
template <typename T>
|
|
3308
3606
|
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceAccessor(
|
|
3309
3607
|
const char* utf8name,
|
|
@@ -3342,6 +3640,38 @@ inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceAccessor(
|
|
|
3342
3640
|
return desc;
|
|
3343
3641
|
}
|
|
3344
3642
|
|
|
3643
|
+
template <typename T>
|
|
3644
|
+
template <typename ObjectWrap<T>::InstanceGetterCallback getter,
|
|
3645
|
+
typename ObjectWrap<T>::InstanceSetterCallback setter>
|
|
3646
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceAccessor(
|
|
3647
|
+
const char* utf8name,
|
|
3648
|
+
napi_property_attributes attributes,
|
|
3649
|
+
void* data) {
|
|
3650
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3651
|
+
desc.utf8name = utf8name;
|
|
3652
|
+
desc.getter = This::WrapGetter(This::GetterTag<getter>());
|
|
3653
|
+
desc.setter = This::WrapSetter(This::SetterTag<setter>());
|
|
3654
|
+
desc.data = data;
|
|
3655
|
+
desc.attributes = attributes;
|
|
3656
|
+
return desc;
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
template <typename T>
|
|
3660
|
+
template <typename ObjectWrap<T>::InstanceGetterCallback getter,
|
|
3661
|
+
typename ObjectWrap<T>::InstanceSetterCallback setter>
|
|
3662
|
+
inline ClassPropertyDescriptor<T> ObjectWrap<T>::InstanceAccessor(
|
|
3663
|
+
Symbol name,
|
|
3664
|
+
napi_property_attributes attributes,
|
|
3665
|
+
void* data) {
|
|
3666
|
+
napi_property_descriptor desc = napi_property_descriptor();
|
|
3667
|
+
desc.name = name;
|
|
3668
|
+
desc.getter = This::WrapGetter(This::GetterTag<getter>());
|
|
3669
|
+
desc.setter = This::WrapSetter(This::SetterTag<setter>());
|
|
3670
|
+
desc.data = data;
|
|
3671
|
+
desc.attributes = attributes;
|
|
3672
|
+
return desc;
|
|
3673
|
+
}
|
|
3674
|
+
|
|
3345
3675
|
template <typename T>
|
|
3346
3676
|
inline ClassPropertyDescriptor<T> ObjectWrap<T>::StaticValue(const char* utf8name,
|
|
3347
3677
|
Napi::Value value, napi_property_attributes attributes) {
|
|
@@ -3547,6 +3877,65 @@ inline void ObjectWrap<T>::FinalizeCallback(napi_env env, void* data, void* /*hi
|
|
|
3547
3877
|
delete instance;
|
|
3548
3878
|
}
|
|
3549
3879
|
|
|
3880
|
+
template <typename T>
|
|
3881
|
+
template <typename ObjectWrap<T>::StaticVoidMethodCallback method>
|
|
3882
|
+
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3883
|
+
return details::WrapCallback([&] {
|
|
3884
|
+
method(CallbackInfo(env, info));
|
|
3885
|
+
return nullptr;
|
|
3886
|
+
});
|
|
3887
|
+
}
|
|
3888
|
+
|
|
3889
|
+
template <typename T>
|
|
3890
|
+
template <typename ObjectWrap<T>::StaticMethodCallback method>
|
|
3891
|
+
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3892
|
+
return details::WrapCallback([&] {
|
|
3893
|
+
return method(CallbackInfo(env, info));
|
|
3894
|
+
});
|
|
3895
|
+
}
|
|
3896
|
+
|
|
3897
|
+
template <typename T>
|
|
3898
|
+
template <typename ObjectWrap<T>::InstanceVoidMethodCallback method>
|
|
3899
|
+
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3900
|
+
return details::WrapCallback([&] {
|
|
3901
|
+
const CallbackInfo cbInfo(env, info);
|
|
3902
|
+
T* instance = Unwrap(cbInfo.This().As<Object>());
|
|
3903
|
+
(instance->*method)(cbInfo);
|
|
3904
|
+
return nullptr;
|
|
3905
|
+
});
|
|
3906
|
+
}
|
|
3907
|
+
|
|
3908
|
+
template <typename T>
|
|
3909
|
+
template <typename ObjectWrap<T>::InstanceMethodCallback method>
|
|
3910
|
+
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3911
|
+
return details::WrapCallback([&] {
|
|
3912
|
+
const CallbackInfo cbInfo(env, info);
|
|
3913
|
+
T* instance = Unwrap(cbInfo.This().As<Object>());
|
|
3914
|
+
return (instance->*method)(cbInfo);
|
|
3915
|
+
});
|
|
3916
|
+
}
|
|
3917
|
+
|
|
3918
|
+
template <typename T>
|
|
3919
|
+
template <typename ObjectWrap<T>::StaticSetterCallback method>
|
|
3920
|
+
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3921
|
+
return details::WrapCallback([&] {
|
|
3922
|
+
const CallbackInfo cbInfo(env, info);
|
|
3923
|
+
method(cbInfo, cbInfo[0]);
|
|
3924
|
+
return nullptr;
|
|
3925
|
+
});
|
|
3926
|
+
}
|
|
3927
|
+
|
|
3928
|
+
template <typename T>
|
|
3929
|
+
template <typename ObjectWrap<T>::InstanceSetterCallback method>
|
|
3930
|
+
inline napi_value ObjectWrap<T>::WrappedMethod(napi_env env, napi_callback_info info) noexcept {
|
|
3931
|
+
return details::WrapCallback([&] {
|
|
3932
|
+
const CallbackInfo cbInfo(env, info);
|
|
3933
|
+
T* instance = Unwrap(cbInfo.This().As<Object>());
|
|
3934
|
+
(instance->*method)(cbInfo, cbInfo[0]);
|
|
3935
|
+
return nullptr;
|
|
3936
|
+
});
|
|
3937
|
+
}
|
|
3938
|
+
|
|
3550
3939
|
////////////////////////////////////////////////////////////////////////////////
|
|
3551
3940
|
// HandleScope class
|
|
3552
3941
|
////////////////////////////////////////////////////////////////////////////////
|
|
@@ -3744,8 +4133,8 @@ inline AsyncWorker::AsyncWorker(const Object& receiver,
|
|
|
3744
4133
|
_env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
|
|
3745
4134
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3746
4135
|
|
|
3747
|
-
status = napi_create_async_work(_env, resource, resource_id,
|
|
3748
|
-
|
|
4136
|
+
status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute,
|
|
4137
|
+
OnAsyncWorkComplete, this, &_work);
|
|
3749
4138
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3750
4139
|
}
|
|
3751
4140
|
|
|
@@ -3770,8 +4159,8 @@ inline AsyncWorker::AsyncWorker(Napi::Env env,
|
|
|
3770
4159
|
_env, resource_name, NAPI_AUTO_LENGTH, &resource_id);
|
|
3771
4160
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3772
4161
|
|
|
3773
|
-
status = napi_create_async_work(_env, resource, resource_id,
|
|
3774
|
-
|
|
4162
|
+
status = napi_create_async_work(_env, resource, resource_id, OnAsyncWorkExecute,
|
|
4163
|
+
OnAsyncWorkComplete, this, &_work);
|
|
3775
4164
|
NAPI_THROW_IF_FAILED_VOID(_env, status);
|
|
3776
4165
|
}
|
|
3777
4166
|
|
|
@@ -3858,40 +4247,51 @@ inline void AsyncWorker::SetError(const std::string& error) {
|
|
|
3858
4247
|
inline std::vector<napi_value> AsyncWorker::GetResult(Napi::Env /*env*/) {
|
|
3859
4248
|
return {};
|
|
3860
4249
|
}
|
|
4250
|
+
// The OnAsyncWorkExecute method receives an napi_env argument. However, do NOT
|
|
4251
|
+
// use it within this method, as it does not run on the JavaScript thread and
|
|
4252
|
+
// must not run any method that would cause JavaScript to run. In practice,
|
|
4253
|
+
// this means that almost any use of napi_env will be incorrect.
|
|
4254
|
+
inline void AsyncWorker::OnAsyncWorkExecute(napi_env env, void* asyncworker) {
|
|
4255
|
+
AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
|
|
4256
|
+
self->OnExecute(env);
|
|
4257
|
+
}
|
|
3861
4258
|
// The OnExecute method receives an napi_env argument. However, do NOT
|
|
3862
|
-
// use it within this method, as it does not run on the
|
|
3863
|
-
// not run any method that would cause JavaScript to run. In practice,
|
|
3864
|
-
// means that almost any use of napi_env will be incorrect.
|
|
3865
|
-
inline void AsyncWorker::OnExecute(
|
|
3866
|
-
AsyncWorker* self = static_cast<AsyncWorker*>(this_pointer);
|
|
4259
|
+
// use it within this method, as it does not run on the JavaScript thread and
|
|
4260
|
+
// must not run any method that would cause JavaScript to run. In practice,
|
|
4261
|
+
// this means that almost any use of napi_env will be incorrect.
|
|
4262
|
+
inline void AsyncWorker::OnExecute(Napi::Env /*DO_NOT_USE*/) {
|
|
3867
4263
|
#ifdef NAPI_CPP_EXCEPTIONS
|
|
3868
4264
|
try {
|
|
3869
|
-
|
|
4265
|
+
Execute();
|
|
3870
4266
|
} catch (const std::exception& e) {
|
|
3871
|
-
|
|
4267
|
+
SetError(e.what());
|
|
3872
4268
|
}
|
|
3873
4269
|
#else // NAPI_CPP_EXCEPTIONS
|
|
3874
|
-
|
|
4270
|
+
Execute();
|
|
3875
4271
|
#endif // NAPI_CPP_EXCEPTIONS
|
|
3876
4272
|
}
|
|
3877
4273
|
|
|
3878
|
-
inline void AsyncWorker::
|
|
3879
|
-
|
|
3880
|
-
|
|
4274
|
+
inline void AsyncWorker::OnAsyncWorkComplete(napi_env env,
|
|
4275
|
+
napi_status status,
|
|
4276
|
+
void* asyncworker) {
|
|
4277
|
+
AsyncWorker* self = static_cast<AsyncWorker*>(asyncworker);
|
|
4278
|
+
self->OnWorkComplete(env, status);
|
|
4279
|
+
}
|
|
4280
|
+
inline void AsyncWorker::OnWorkComplete(Napi::Env /*env*/, napi_status status) {
|
|
3881
4281
|
if (status != napi_cancelled) {
|
|
3882
|
-
HandleScope scope(
|
|
4282
|
+
HandleScope scope(_env);
|
|
3883
4283
|
details::WrapCallback([&] {
|
|
3884
|
-
if (
|
|
3885
|
-
|
|
4284
|
+
if (_error.size() == 0) {
|
|
4285
|
+
OnOK();
|
|
3886
4286
|
}
|
|
3887
4287
|
else {
|
|
3888
|
-
|
|
4288
|
+
OnError(Error::New(_env, _error));
|
|
3889
4289
|
}
|
|
3890
4290
|
return nullptr;
|
|
3891
4291
|
});
|
|
3892
4292
|
}
|
|
3893
|
-
if (!
|
|
3894
|
-
|
|
4293
|
+
if (!_suppress_destruct) {
|
|
4294
|
+
Destroy();
|
|
3895
4295
|
}
|
|
3896
4296
|
}
|
|
3897
4297
|
|
|
@@ -4187,7 +4587,7 @@ inline ThreadSafeFunction ThreadSafeFunction::New(napi_env env,
|
|
|
4187
4587
|
|
|
4188
4588
|
ThreadSafeFunction tsfn;
|
|
4189
4589
|
auto* finalizeData = new details::ThreadSafeFinalize<ContextType, Finalizer,
|
|
4190
|
-
FinalizerDataType>({ data, finalizeCallback
|
|
4590
|
+
FinalizerDataType>({ data, finalizeCallback });
|
|
4191
4591
|
napi_status status = napi_create_threadsafe_function(env, callback, resource,
|
|
4192
4592
|
Value::From(env, resourceName), maxQueueSize, initialThreadCount,
|
|
4193
4593
|
finalizeData, wrapper, context, CallJS, &tsfn._tsfn);
|
|
@@ -4230,9 +4630,89 @@ inline void ThreadSafeFunction::CallJS(napi_env env,
|
|
|
4230
4630
|
}
|
|
4231
4631
|
|
|
4232
4632
|
////////////////////////////////////////////////////////////////////////////////
|
|
4233
|
-
// Async Progress Worker class
|
|
4633
|
+
// Async Progress Worker Base class
|
|
4234
4634
|
////////////////////////////////////////////////////////////////////////////////
|
|
4635
|
+
template <typename DataType>
|
|
4636
|
+
inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(const Object& receiver,
|
|
4637
|
+
const Function& callback,
|
|
4638
|
+
const char* resource_name,
|
|
4639
|
+
const Object& resource,
|
|
4640
|
+
size_t queue_size)
|
|
4641
|
+
: AsyncWorker(receiver, callback, resource_name, resource) {
|
|
4642
|
+
// Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures.
|
|
4643
|
+
_tsfn = ThreadSafeFunction::New(callback.Env(),
|
|
4644
|
+
callback,
|
|
4645
|
+
resource,
|
|
4646
|
+
resource_name,
|
|
4647
|
+
queue_size,
|
|
4648
|
+
/** initialThreadCount */ 1,
|
|
4649
|
+
/** context */ this,
|
|
4650
|
+
OnThreadSafeFunctionFinalize,
|
|
4651
|
+
/** finalizeData */ this);
|
|
4652
|
+
}
|
|
4653
|
+
|
|
4654
|
+
#if NAPI_VERSION > 4
|
|
4655
|
+
template <typename DataType>
|
|
4656
|
+
inline AsyncProgressWorkerBase<DataType>::AsyncProgressWorkerBase(Napi::Env env,
|
|
4657
|
+
const char* resource_name,
|
|
4658
|
+
const Object& resource,
|
|
4659
|
+
size_t queue_size)
|
|
4660
|
+
: AsyncWorker(env, resource_name, resource) {
|
|
4661
|
+
// TODO: Once the changes to make the callback optional for threadsafe
|
|
4662
|
+
// functions are available on all versions we can remove the dummy Function here.
|
|
4663
|
+
Function callback;
|
|
4664
|
+
// Fill all possible arguments to work around ambiguous ThreadSafeFunction::New signatures.
|
|
4665
|
+
_tsfn = ThreadSafeFunction::New(env,
|
|
4666
|
+
callback,
|
|
4667
|
+
resource,
|
|
4668
|
+
resource_name,
|
|
4669
|
+
queue_size,
|
|
4670
|
+
/** initialThreadCount */ 1,
|
|
4671
|
+
/** context */ this,
|
|
4672
|
+
OnThreadSafeFunctionFinalize,
|
|
4673
|
+
/** finalizeData */ this);
|
|
4674
|
+
}
|
|
4675
|
+
#endif
|
|
4676
|
+
|
|
4677
|
+
template<typename DataType>
|
|
4678
|
+
inline AsyncProgressWorkerBase<DataType>::~AsyncProgressWorkerBase() {
|
|
4679
|
+
// Abort pending tsfn call.
|
|
4680
|
+
// Don't send progress events after we've already completed.
|
|
4681
|
+
// It's ok to call ThreadSafeFunction::Abort and ThreadSafeFunction::Release duplicated.
|
|
4682
|
+
_tsfn.Abort();
|
|
4683
|
+
}
|
|
4684
|
+
|
|
4685
|
+
template <typename DataType>
|
|
4686
|
+
inline void AsyncProgressWorkerBase<DataType>::OnAsyncWorkProgress(Napi::Env /* env */,
|
|
4687
|
+
Napi::Function /* jsCallback */,
|
|
4688
|
+
void* data) {
|
|
4689
|
+
ThreadSafeData* tsd = static_cast<ThreadSafeData*>(data);
|
|
4690
|
+
tsd->asyncprogressworker()->OnWorkProgress(tsd->data());
|
|
4691
|
+
}
|
|
4692
|
+
|
|
4693
|
+
template <typename DataType>
|
|
4694
|
+
inline napi_status AsyncProgressWorkerBase<DataType>::NonBlockingCall(DataType* data) {
|
|
4695
|
+
auto tsd = new AsyncProgressWorkerBase::ThreadSafeData(this, data);
|
|
4696
|
+
return _tsfn.NonBlockingCall(tsd, OnAsyncWorkProgress);
|
|
4697
|
+
}
|
|
4698
|
+
|
|
4699
|
+
template <typename DataType>
|
|
4700
|
+
inline void AsyncProgressWorkerBase<DataType>::OnWorkComplete(Napi::Env /* env */, napi_status status) {
|
|
4701
|
+
_work_completed = true;
|
|
4702
|
+
_complete_status = status;
|
|
4703
|
+
_tsfn.Release();
|
|
4704
|
+
}
|
|
4235
4705
|
|
|
4706
|
+
template <typename DataType>
|
|
4707
|
+
inline void AsyncProgressWorkerBase<DataType>::OnThreadSafeFunctionFinalize(Napi::Env env, void* /* data */, AsyncProgressWorkerBase* context) {
|
|
4708
|
+
if (context->_work_completed) {
|
|
4709
|
+
context->AsyncWorker::OnWorkComplete(env, context->_complete_status);
|
|
4710
|
+
}
|
|
4711
|
+
}
|
|
4712
|
+
|
|
4713
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4714
|
+
// Async Progress Worker class
|
|
4715
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4236
4716
|
template<class T>
|
|
4237
4717
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback)
|
|
4238
4718
|
: AsyncProgressWorker(callback, "generic") {
|
|
@@ -4256,14 +4736,14 @@ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Function& callback,
|
|
|
4256
4736
|
|
|
4257
4737
|
template<class T>
|
|
4258
4738
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
|
|
4259
|
-
|
|
4739
|
+
const Function& callback)
|
|
4260
4740
|
: AsyncProgressWorker(receiver, callback, "generic") {
|
|
4261
4741
|
}
|
|
4262
4742
|
|
|
4263
4743
|
template<class T>
|
|
4264
4744
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
|
|
4265
|
-
|
|
4266
|
-
|
|
4745
|
+
const Function& callback,
|
|
4746
|
+
const char* resource_name)
|
|
4267
4747
|
: AsyncProgressWorker(receiver,
|
|
4268
4748
|
callback,
|
|
4269
4749
|
resource_name,
|
|
@@ -4275,10 +4755,9 @@ inline AsyncProgressWorker<T>::AsyncProgressWorker(const Object& receiver,
|
|
|
4275
4755
|
const Function& callback,
|
|
4276
4756
|
const char* resource_name,
|
|
4277
4757
|
const Object& resource)
|
|
4278
|
-
:
|
|
4758
|
+
: AsyncProgressWorkerBase(receiver, callback, resource_name, resource),
|
|
4279
4759
|
_asyncdata(nullptr),
|
|
4280
4760
|
_asyncsize(0) {
|
|
4281
|
-
_tsfn = ThreadSafeFunction::New(callback.Env(), callback, resource_name, 1, 1);
|
|
4282
4761
|
}
|
|
4283
4762
|
|
|
4284
4763
|
#if NAPI_VERSION > 4
|
|
@@ -4289,35 +4768,27 @@ inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env)
|
|
|
4289
4768
|
|
|
4290
4769
|
template<class T>
|
|
4291
4770
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
|
|
4292
|
-
|
|
4771
|
+
const char* resource_name)
|
|
4293
4772
|
: AsyncProgressWorker(env, resource_name, Object::New(env)) {
|
|
4294
4773
|
}
|
|
4295
4774
|
|
|
4296
4775
|
template<class T>
|
|
4297
4776
|
inline AsyncProgressWorker<T>::AsyncProgressWorker(Napi::Env env,
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
:
|
|
4777
|
+
const char* resource_name,
|
|
4778
|
+
const Object& resource)
|
|
4779
|
+
: AsyncProgressWorkerBase(env, resource_name, resource),
|
|
4301
4780
|
_asyncdata(nullptr),
|
|
4302
4781
|
_asyncsize(0) {
|
|
4303
|
-
// TODO: Once the changes to make the callback optional for threadsafe
|
|
4304
|
-
// functions are no longer optional we can remove the dummy Function here.
|
|
4305
|
-
Function callback;
|
|
4306
|
-
_tsfn = ThreadSafeFunction::New(env, callback, resource_name, 1, 1);
|
|
4307
4782
|
}
|
|
4308
4783
|
#endif
|
|
4309
4784
|
|
|
4310
4785
|
template<class T>
|
|
4311
4786
|
inline AsyncProgressWorker<T>::~AsyncProgressWorker() {
|
|
4312
|
-
// Abort pending tsfn call.
|
|
4313
|
-
// Don't send progress events after we've already completed.
|
|
4314
|
-
_tsfn.Abort();
|
|
4315
4787
|
{
|
|
4316
|
-
std::lock_guard<std::mutex> lock(_mutex);
|
|
4788
|
+
std::lock_guard<std::mutex> lock(this->_mutex);
|
|
4317
4789
|
_asyncdata = nullptr;
|
|
4318
4790
|
_asyncsize = 0;
|
|
4319
4791
|
}
|
|
4320
|
-
_tsfn.Release();
|
|
4321
4792
|
}
|
|
4322
4793
|
|
|
4323
4794
|
template<class T>
|
|
@@ -4327,20 +4798,18 @@ inline void AsyncProgressWorker<T>::Execute() {
|
|
|
4327
4798
|
}
|
|
4328
4799
|
|
|
4329
4800
|
template<class T>
|
|
4330
|
-
inline void AsyncProgressWorker<T>::
|
|
4331
|
-
AsyncProgressWorker* self = static_cast<AsyncProgressWorker*>(_data);
|
|
4332
|
-
|
|
4801
|
+
inline void AsyncProgressWorker<T>::OnWorkProgress(void*) {
|
|
4333
4802
|
T* data;
|
|
4334
4803
|
size_t size;
|
|
4335
4804
|
{
|
|
4336
|
-
std::lock_guard<std::mutex> lock(
|
|
4337
|
-
data =
|
|
4338
|
-
size =
|
|
4339
|
-
|
|
4340
|
-
|
|
4805
|
+
std::lock_guard<std::mutex> lock(this->_mutex);
|
|
4806
|
+
data = this->_asyncdata;
|
|
4807
|
+
size = this->_asyncsize;
|
|
4808
|
+
this->_asyncdata = nullptr;
|
|
4809
|
+
this->_asyncsize = 0;
|
|
4341
4810
|
}
|
|
4342
4811
|
|
|
4343
|
-
|
|
4812
|
+
this->OnProgress(data, size);
|
|
4344
4813
|
delete[] data;
|
|
4345
4814
|
}
|
|
4346
4815
|
|
|
@@ -4351,19 +4820,19 @@ inline void AsyncProgressWorker<T>::SendProgress_(const T* data, size_t count) {
|
|
|
4351
4820
|
|
|
4352
4821
|
T* old_data;
|
|
4353
4822
|
{
|
|
4354
|
-
std::lock_guard<std::mutex> lock(_mutex);
|
|
4823
|
+
std::lock_guard<std::mutex> lock(this->_mutex);
|
|
4355
4824
|
old_data = _asyncdata;
|
|
4356
4825
|
_asyncdata = new_data;
|
|
4357
4826
|
_asyncsize = count;
|
|
4358
4827
|
}
|
|
4359
|
-
|
|
4828
|
+
this->NonBlockingCall(nullptr);
|
|
4360
4829
|
|
|
4361
4830
|
delete[] old_data;
|
|
4362
4831
|
}
|
|
4363
4832
|
|
|
4364
4833
|
template<class T>
|
|
4365
4834
|
inline void AsyncProgressWorker<T>::Signal() const {
|
|
4366
|
-
|
|
4835
|
+
this->NonBlockingCall(static_cast<T*>(nullptr));
|
|
4367
4836
|
}
|
|
4368
4837
|
|
|
4369
4838
|
template<class T>
|
|
@@ -4376,6 +4845,123 @@ inline void AsyncProgressWorker<T>::ExecutionProgress::Send(const T* data, size_
|
|
|
4376
4845
|
_worker->SendProgress_(data, count);
|
|
4377
4846
|
}
|
|
4378
4847
|
|
|
4848
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4849
|
+
// Async Progress Queue Worker class
|
|
4850
|
+
////////////////////////////////////////////////////////////////////////////////
|
|
4851
|
+
template<class T>
|
|
4852
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback)
|
|
4853
|
+
: AsyncProgressQueueWorker(callback, "generic") {
|
|
4854
|
+
}
|
|
4855
|
+
|
|
4856
|
+
template<class T>
|
|
4857
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback,
|
|
4858
|
+
const char* resource_name)
|
|
4859
|
+
: AsyncProgressQueueWorker(callback, resource_name, Object::New(callback.Env())) {
|
|
4860
|
+
}
|
|
4861
|
+
|
|
4862
|
+
template<class T>
|
|
4863
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Function& callback,
|
|
4864
|
+
const char* resource_name,
|
|
4865
|
+
const Object& resource)
|
|
4866
|
+
: AsyncProgressQueueWorker(Object::New(callback.Env()),
|
|
4867
|
+
callback,
|
|
4868
|
+
resource_name,
|
|
4869
|
+
resource) {
|
|
4870
|
+
}
|
|
4871
|
+
|
|
4872
|
+
template<class T>
|
|
4873
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
|
|
4874
|
+
const Function& callback)
|
|
4875
|
+
: AsyncProgressQueueWorker(receiver, callback, "generic") {
|
|
4876
|
+
}
|
|
4877
|
+
|
|
4878
|
+
template<class T>
|
|
4879
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
|
|
4880
|
+
const Function& callback,
|
|
4881
|
+
const char* resource_name)
|
|
4882
|
+
: AsyncProgressQueueWorker(receiver,
|
|
4883
|
+
callback,
|
|
4884
|
+
resource_name,
|
|
4885
|
+
Object::New(callback.Env())) {
|
|
4886
|
+
}
|
|
4887
|
+
|
|
4888
|
+
template<class T>
|
|
4889
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(const Object& receiver,
|
|
4890
|
+
const Function& callback,
|
|
4891
|
+
const char* resource_name,
|
|
4892
|
+
const Object& resource)
|
|
4893
|
+
: AsyncProgressWorkerBase<std::pair<T*, size_t>>(receiver, callback, resource_name, resource, /** unlimited queue size */0) {
|
|
4894
|
+
}
|
|
4895
|
+
|
|
4896
|
+
#if NAPI_VERSION > 4
|
|
4897
|
+
template<class T>
|
|
4898
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env)
|
|
4899
|
+
: AsyncProgressQueueWorker(env, "generic") {
|
|
4900
|
+
}
|
|
4901
|
+
|
|
4902
|
+
template<class T>
|
|
4903
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env,
|
|
4904
|
+
const char* resource_name)
|
|
4905
|
+
: AsyncProgressQueueWorker(env, resource_name, Object::New(env)) {
|
|
4906
|
+
}
|
|
4907
|
+
|
|
4908
|
+
template<class T>
|
|
4909
|
+
inline AsyncProgressQueueWorker<T>::AsyncProgressQueueWorker(Napi::Env env,
|
|
4910
|
+
const char* resource_name,
|
|
4911
|
+
const Object& resource)
|
|
4912
|
+
: AsyncProgressWorkerBase<std::pair<T*, size_t>>(env, resource_name, resource, /** unlimited queue size */0) {
|
|
4913
|
+
}
|
|
4914
|
+
#endif
|
|
4915
|
+
|
|
4916
|
+
template<class T>
|
|
4917
|
+
inline void AsyncProgressQueueWorker<T>::Execute() {
|
|
4918
|
+
ExecutionProgress progress(this);
|
|
4919
|
+
Execute(progress);
|
|
4920
|
+
}
|
|
4921
|
+
|
|
4922
|
+
template<class T>
|
|
4923
|
+
inline void AsyncProgressQueueWorker<T>::OnWorkProgress(std::pair<T*, size_t>* datapair) {
|
|
4924
|
+
if (datapair == nullptr) {
|
|
4925
|
+
return;
|
|
4926
|
+
}
|
|
4927
|
+
|
|
4928
|
+
T *data = datapair->first;
|
|
4929
|
+
size_t size = datapair->second;
|
|
4930
|
+
|
|
4931
|
+
this->OnProgress(data, size);
|
|
4932
|
+
delete datapair;
|
|
4933
|
+
delete[] data;
|
|
4934
|
+
}
|
|
4935
|
+
|
|
4936
|
+
template<class T>
|
|
4937
|
+
inline void AsyncProgressQueueWorker<T>::SendProgress_(const T* data, size_t count) {
|
|
4938
|
+
T* new_data = new T[count];
|
|
4939
|
+
std::copy(data, data + count, new_data);
|
|
4940
|
+
|
|
4941
|
+
auto pair = new std::pair<T*, size_t>(new_data, count);
|
|
4942
|
+
this->NonBlockingCall(pair);
|
|
4943
|
+
}
|
|
4944
|
+
|
|
4945
|
+
template<class T>
|
|
4946
|
+
inline void AsyncProgressQueueWorker<T>::Signal() const {
|
|
4947
|
+
this->NonBlockingCall(nullptr);
|
|
4948
|
+
}
|
|
4949
|
+
|
|
4950
|
+
template<class T>
|
|
4951
|
+
inline void AsyncProgressQueueWorker<T>::OnWorkComplete(Napi::Env env, napi_status status) {
|
|
4952
|
+
// Draining queued items in TSFN.
|
|
4953
|
+
AsyncProgressWorkerBase<std::pair<T*, size_t>>::OnWorkComplete(env, status);
|
|
4954
|
+
}
|
|
4955
|
+
|
|
4956
|
+
template<class T>
|
|
4957
|
+
inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Signal() const {
|
|
4958
|
+
_worker->Signal();
|
|
4959
|
+
}
|
|
4960
|
+
|
|
4961
|
+
template<class T>
|
|
4962
|
+
inline void AsyncProgressQueueWorker<T>::ExecutionProgress::Send(const T* data, size_t count) const {
|
|
4963
|
+
_worker->SendProgress_(data, count);
|
|
4964
|
+
}
|
|
4379
4965
|
#endif
|
|
4380
4966
|
|
|
4381
4967
|
////////////////////////////////////////////////////////////////////////////////
|