koffi 2.3.4 → 2.3.6-beta.1
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/CHANGELOG.md +25 -2
- package/doc/changelog.md +4 -0
- package/doc/index.rst +1 -2
- package/doc/types.md +3 -3
- package/package.json +5 -5
- package/src/cnoke/cnoke.js +40 -834
- package/src/cnoke/package.json +1 -0
- package/src/cnoke/src/builder.js +447 -0
- package/src/cnoke/src/index.js +20 -0
- package/src/cnoke/src/tools.js +401 -0
- package/src/core/libcc/libcc.cc +2 -2
- package/src/koffi/build/2.3.6-beta.1/koffi_darwin_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_darwin_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm32hf/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_riscv64hf64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_linux_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.pdb +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.exp +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.lib +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.node +0 -0
- package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.pdb +0 -0
- package/src/koffi/src/abi_arm32.cc +43 -14
- package/src/koffi/src/abi_arm64.cc +95 -21
- package/src/koffi/src/abi_riscv64.cc +125 -64
- package/src/koffi/src/abi_x64_sysv.cc +38 -20
- package/src/koffi/src/abi_x64_win.cc +11 -5
- package/src/koffi/src/abi_x86.cc +14 -7
- package/src/koffi/src/call.cc +114 -44
- package/src/koffi/src/call.hh +6 -4
- package/src/koffi/src/ffi.cc +172 -147
- package/src/koffi/src/ffi.hh +18 -10
- package/src/koffi/src/index.d.ts +28 -7
- package/src/koffi/src/index.js +23 -4
- package/src/koffi/src/util.cc +261 -69
- package/src/koffi/src/util.hh +34 -8
- package/vendor/node-addon-api/CHANGELOG.md +122 -9
- package/vendor/node-addon-api/CONTRIBUTING.md +10 -10
- package/vendor/node-addon-api/README.md +36 -12
- package/vendor/node-addon-api/benchmark/function_args.cc +95 -62
- package/vendor/node-addon-api/benchmark/function_args.js +6 -6
- package/vendor/node-addon-api/benchmark/index.js +1 -1
- package/vendor/node-addon-api/benchmark/property_descriptor.cc +27 -34
- package/vendor/node-addon-api/benchmark/property_descriptor.js +5 -4
- package/vendor/node-addon-api/doc/async_operations.md +1 -1
- package/vendor/node-addon-api/doc/async_worker_variants.md +23 -2
- package/vendor/node-addon-api/doc/cmake-js.md +1 -1
- package/vendor/node-addon-api/doc/error_handling.md +3 -3
- package/vendor/node-addon-api/doc/external.md +7 -0
- package/vendor/node-addon-api/doc/handle_scope.md +14 -0
- package/vendor/node-addon-api/doc/hierarchy.md +1 -1
- package/vendor/node-addon-api/doc/object.md +27 -0
- package/vendor/node-addon-api/index.js +3 -3
- package/vendor/node-addon-api/napi-inl.deprecated.h +121 -127
- package/vendor/node-addon-api/napi-inl.h +1178 -1144
- package/vendor/node-addon-api/napi.h +2786 -2675
- package/vendor/node-addon-api/package.json +42 -1
- package/vendor/node-addon-api/test/addon.cc +8 -6
- package/vendor/node-addon-api/test/addon_build/index.js +9 -9
- package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +2 -1
- package/vendor/node-addon-api/test/addon_build/tpl/index.js +4 -4
- package/vendor/node-addon-api/test/addon_data.cc +12 -13
- package/vendor/node-addon-api/test/array_buffer.js +3 -2
- package/vendor/node-addon-api/test/async_progress_queue_worker.cc +13 -3
- package/vendor/node-addon-api/test/async_progress_queue_worker.js +5 -5
- package/vendor/node-addon-api/test/async_progress_worker.cc +65 -9
- package/vendor/node-addon-api/test/async_progress_worker.js +14 -9
- package/vendor/node-addon-api/test/async_worker.cc +236 -3
- package/vendor/node-addon-api/test/async_worker.js +122 -37
- package/vendor/node-addon-api/test/async_worker_nocallback.js +9 -3
- package/vendor/node-addon-api/test/async_worker_persistent.js +2 -2
- package/vendor/node-addon-api/test/basic_types/array.js +3 -4
- package/vendor/node-addon-api/test/basic_types/boolean.cc +4 -2
- package/vendor/node-addon-api/test/basic_types/boolean.js +1 -2
- package/vendor/node-addon-api/test/basic_types/number.cc +12 -6
- package/vendor/node-addon-api/test/basic_types/number.js +19 -18
- package/vendor/node-addon-api/test/basic_types/value.cc +52 -1
- package/vendor/node-addon-api/test/basic_types/value.js +44 -21
- package/vendor/node-addon-api/test/bigint.cc +2 -1
- package/vendor/node-addon-api/test/binding.cc +11 -5
- package/vendor/node-addon-api/test/binding.gyp +3 -1
- package/vendor/node-addon-api/test/buffer.cc +46 -38
- package/vendor/node-addon-api/test/buffer.js +12 -12
- package/vendor/node-addon-api/test/callbackInfo.cc +27 -0
- package/vendor/node-addon-api/test/callbackInfo.js +9 -0
- package/vendor/node-addon-api/test/callbackscope.cc +19 -2
- package/vendor/node-addon-api/test/callbackscope.js +20 -20
- package/vendor/node-addon-api/test/common/index.js +37 -4
- package/vendor/node-addon-api/test/dataview/dataview.js +5 -5
- package/vendor/node-addon-api/test/dataview/dataview_read_write.js +14 -12
- package/vendor/node-addon-api/test/date.cc +2 -1
- package/vendor/node-addon-api/test/date.js +2 -2
- package/vendor/node-addon-api/test/env_cleanup.cc +12 -0
- package/vendor/node-addon-api/test/env_cleanup.js +38 -39
- package/vendor/node-addon-api/test/error.cc +6 -5
- package/vendor/node-addon-api/test/error_terminating_environment.js +64 -60
- package/vendor/node-addon-api/test/external.cc +36 -32
- package/vendor/node-addon-api/test/external.js +43 -46
- package/vendor/node-addon-api/test/function.cc +58 -44
- package/vendor/node-addon-api/test/function.js +4 -0
- package/vendor/node-addon-api/test/function_reference.cc +15 -13
- package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +50 -53
- package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +33 -34
- package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +38 -40
- package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +47 -49
- package/vendor/node-addon-api/test/handlescope.cc +29 -3
- package/vendor/node-addon-api/test/handlescope.js +5 -3
- package/vendor/node-addon-api/test/index.js +1 -5
- package/vendor/node-addon-api/test/maybe/check.cc +49 -3
- package/vendor/node-addon-api/test/maybe/index.js +19 -7
- package/vendor/node-addon-api/test/memory_management.cc +9 -8
- package/vendor/node-addon-api/test/memory_management.js +2 -2
- package/vendor/node-addon-api/test/movable_callbacks.js +2 -2
- package/vendor/node-addon-api/test/name.js +3 -3
- package/vendor/node-addon-api/test/napi_child.js +2 -2
- package/vendor/node-addon-api/test/object/delete_property.js +7 -7
- package/vendor/node-addon-api/test/object/finalizer.cc +13 -12
- package/vendor/node-addon-api/test/object/finalizer.js +2 -2
- package/vendor/node-addon-api/test/object/get_property.js +6 -6
- package/vendor/node-addon-api/test/object/has_own_property.js +3 -3
- package/vendor/node-addon-api/test/object/has_property.js +4 -4
- package/vendor/node-addon-api/test/object/object.cc +191 -111
- package/vendor/node-addon-api/test/object/object.js +53 -52
- package/vendor/node-addon-api/test/object/object_deprecated.cc +24 -20
- package/vendor/node-addon-api/test/object/object_deprecated.js +3 -8
- package/vendor/node-addon-api/test/object/object_freeze_seal.js +54 -54
- package/vendor/node-addon-api/test/object/object_type_tag.cc +39 -0
- package/vendor/node-addon-api/test/object/object_type_tag.js +55 -0
- package/vendor/node-addon-api/test/object/subscript_operator.js +2 -2
- package/vendor/node-addon-api/test/object_reference.js +100 -100
- package/vendor/node-addon-api/test/objectwrap.cc +41 -34
- package/vendor/node-addon-api/test/objectwrap.js +23 -19
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +5 -5
- package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +1 -1
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +7 -7
- package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +1 -1
- package/vendor/node-addon-api/test/objectwrap_removewrap.js +24 -32
- package/vendor/node-addon-api/test/objectwrap_worker_thread.js +5 -4
- package/vendor/node-addon-api/test/promise.cc +7 -0
- package/vendor/node-addon-api/test/promise.js +3 -1
- package/vendor/node-addon-api/test/reference.cc +1 -1
- package/vendor/node-addon-api/test/reference.js +2 -2
- package/vendor/node-addon-api/test/run_script.cc +1 -1
- package/vendor/node-addon-api/test/symbol.js +59 -66
- package/vendor/node-addon-api/test/testUtil.js +6 -6
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +64 -29
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +71 -34
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +111 -19
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +2 -1
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +36 -26
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +5 -5
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +3 -2
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +1 -1
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +47 -32
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +3 -3
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +22 -9
- package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +76 -31
- package/vendor/node-addon-api/test/thunking_manual.cc +61 -74
- package/vendor/node-addon-api/test/thunking_manual.js +6 -7
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +20 -20
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +19 -19
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +57 -5
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +2 -0
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +5 -5
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +5 -1
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +4 -3
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +3 -3
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +14 -0
- package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +76 -31
- package/vendor/node-addon-api/test/typedarray-bigint.js +2 -2
- package/vendor/node-addon-api/test/typedarray.cc +263 -70
- package/vendor/node-addon-api/test/typedarray.js +44 -10
- package/vendor/node-addon-api/test/version_management.cc +16 -15
- package/vendor/node-addon-api/test/version_management.js +18 -20
- package/vendor/node-addon-api/tools/check-napi.js +13 -14
- package/vendor/node-addon-api/tools/conversion.js +161 -169
- package/vendor/node-addon-api/tools/eslint-format.js +9 -1
- package/vendor/node-addon-api/unit-test/README.md +4 -4
- package/src/koffi/build/2.3.4/koffi_darwin_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_darwin_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_freebsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_arm32hf.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_riscv64hf64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_linux_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_openbsd_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_openbsd_x64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_arm64.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_ia32.tar.gz +0 -0
- package/src/koffi/build/2.3.4/koffi_win32_x64.tar.gz +0 -0
|
@@ -9,21 +9,20 @@ using namespace Napi;
|
|
|
9
9
|
namespace {
|
|
10
10
|
|
|
11
11
|
struct TestContext {
|
|
12
|
-
TestContext(Promise::Deferred
|
|
12
|
+
TestContext(Promise::Deferred&& deferred)
|
|
13
13
|
: deferred(std::move(deferred)), callData(nullptr){};
|
|
14
14
|
|
|
15
15
|
napi_threadsafe_function tsfn;
|
|
16
16
|
Promise::Deferred deferred;
|
|
17
|
-
double
|
|
17
|
+
double* callData;
|
|
18
18
|
|
|
19
19
|
~TestContext() {
|
|
20
|
-
if (callData != nullptr)
|
|
21
|
-
delete callData;
|
|
20
|
+
if (callData != nullptr) delete callData;
|
|
22
21
|
};
|
|
23
22
|
};
|
|
24
23
|
|
|
25
|
-
void FinalizeCB(napi_env env, void
|
|
26
|
-
TestContext
|
|
24
|
+
void FinalizeCB(napi_env env, void* /*finalizeData */, void* context) {
|
|
25
|
+
TestContext* testContext = static_cast<TestContext*>(context);
|
|
27
26
|
if (testContext->callData != nullptr) {
|
|
28
27
|
testContext->deferred.Resolve(Number::New(env, *testContext->callData));
|
|
29
28
|
} else {
|
|
@@ -32,10 +31,12 @@ void FinalizeCB(napi_env env, void * /*finalizeData */, void *context) {
|
|
|
32
31
|
delete testContext;
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
void CallJSWithData(napi_env env,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
void CallJSWithData(napi_env env,
|
|
35
|
+
napi_value /* callback */,
|
|
36
|
+
void* context,
|
|
37
|
+
void* data) {
|
|
38
|
+
TestContext* testContext = static_cast<TestContext*>(context);
|
|
39
|
+
testContext->callData = static_cast<double*>(data);
|
|
39
40
|
|
|
40
41
|
napi_status status =
|
|
41
42
|
napi_release_threadsafe_function(testContext->tsfn, napi_tsfn_release);
|
|
@@ -43,9 +44,11 @@ void CallJSWithData(napi_env env, napi_value /* callback */, void *context,
|
|
|
43
44
|
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
void CallJSNoData(napi_env env,
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
void CallJSNoData(napi_env env,
|
|
48
|
+
napi_value /* callback */,
|
|
49
|
+
void* context,
|
|
50
|
+
void* /*data*/) {
|
|
51
|
+
TestContext* testContext = static_cast<TestContext*>(context);
|
|
49
52
|
testContext->callData = nullptr;
|
|
50
53
|
|
|
51
54
|
napi_status status =
|
|
@@ -54,7 +57,7 @@ void CallJSNoData(napi_env env, napi_value /* callback */, void *context,
|
|
|
54
57
|
NAPI_THROW_IF_FAILED_VOID(env, status);
|
|
55
58
|
}
|
|
56
59
|
|
|
57
|
-
static Value TestCall(const CallbackInfo
|
|
60
|
+
static Value TestCall(const CallbackInfo& info) {
|
|
58
61
|
Napi::Env env = info.Env();
|
|
59
62
|
bool isBlocking = false;
|
|
60
63
|
bool hasData = false;
|
|
@@ -71,15 +74,22 @@ static Value TestCall(const CallbackInfo &info) {
|
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
// Allow optional callback passed from JS. Useful for testing.
|
|
74
|
-
Function cb = Function::New(env, [](const CallbackInfo
|
|
77
|
+
Function cb = Function::New(env, [](const CallbackInfo& /*info*/) {});
|
|
75
78
|
|
|
76
|
-
TestContext
|
|
79
|
+
TestContext* testContext = new TestContext(Napi::Promise::Deferred(env));
|
|
77
80
|
|
|
78
|
-
napi_status status =
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
napi_status status =
|
|
82
|
+
napi_create_threadsafe_function(env,
|
|
83
|
+
cb,
|
|
84
|
+
Object::New(env),
|
|
85
|
+
String::New(env, "Test"),
|
|
86
|
+
0,
|
|
87
|
+
1,
|
|
88
|
+
nullptr, /*finalize data*/
|
|
89
|
+
FinalizeCB,
|
|
90
|
+
testContext,
|
|
91
|
+
hasData ? CallJSWithData : CallJSNoData,
|
|
92
|
+
&testContext->tsfn);
|
|
83
93
|
|
|
84
94
|
NAPI_THROW_IF_FAILED(env, status, Value());
|
|
85
95
|
|
|
@@ -88,22 +98,22 @@ static Value TestCall(const CallbackInfo &info) {
|
|
|
88
98
|
// Test the four napi_threadsafe_function direct-accessing calls
|
|
89
99
|
if (isBlocking) {
|
|
90
100
|
if (hasData) {
|
|
91
|
-
wrapped.BlockingCall(static_cast<void
|
|
101
|
+
wrapped.BlockingCall(static_cast<void*>(new double(std::rand())));
|
|
92
102
|
} else {
|
|
93
|
-
wrapped.BlockingCall(static_cast<void
|
|
103
|
+
wrapped.BlockingCall(static_cast<void*>(nullptr));
|
|
94
104
|
}
|
|
95
105
|
} else {
|
|
96
106
|
if (hasData) {
|
|
97
|
-
wrapped.NonBlockingCall(static_cast<void
|
|
107
|
+
wrapped.NonBlockingCall(static_cast<void*>(new double(std::rand())));
|
|
98
108
|
} else {
|
|
99
|
-
wrapped.NonBlockingCall(static_cast<void
|
|
109
|
+
wrapped.NonBlockingCall(static_cast<void*>(nullptr));
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
112
|
|
|
103
113
|
return testContext->deferred.Promise();
|
|
104
114
|
}
|
|
105
115
|
|
|
106
|
-
}
|
|
116
|
+
} // namespace
|
|
107
117
|
|
|
108
118
|
Object InitThreadSafeFunctionExistingTsfn(Env env) {
|
|
109
119
|
Object exports = Object::New(env);
|
|
@@ -4,11 +4,11 @@ const assert = require('assert');
|
|
|
4
4
|
|
|
5
5
|
module.exports = require('../common').runTest(test);
|
|
6
6
|
|
|
7
|
-
async function test(binding) {
|
|
7
|
+
async function test (binding) {
|
|
8
8
|
const testCall = binding.threadsafe_function_existing_tsfn.testCall;
|
|
9
9
|
|
|
10
|
-
assert.strictEqual(typeof await testCall({ blocking: true,
|
|
11
|
-
assert.strictEqual(typeof await testCall({ blocking: true,
|
|
12
|
-
assert.strictEqual(typeof await testCall({ blocking: false, data: true
|
|
13
|
-
assert.strictEqual(typeof await testCall({ blocking: false, data: false }),
|
|
10
|
+
assert.strictEqual(typeof await testCall({ blocking: true, data: true }), 'number');
|
|
11
|
+
assert.strictEqual(typeof await testCall({ blocking: true, data: false }), 'undefined');
|
|
12
|
+
assert.strictEqual(typeof await testCall({ blocking: false, data: true }), 'number');
|
|
13
|
+
assert.strictEqual(typeof await testCall({ blocking: false, data: false }), 'undefined');
|
|
14
14
|
}
|
|
@@ -9,12 +9,13 @@ namespace {
|
|
|
9
9
|
static Value Test(const CallbackInfo& info) {
|
|
10
10
|
Object resource = info[0].As<Object>();
|
|
11
11
|
Function cb = info[1].As<Function>();
|
|
12
|
-
ThreadSafeFunction tsfn =
|
|
12
|
+
ThreadSafeFunction tsfn =
|
|
13
|
+
ThreadSafeFunction::New(info.Env(), cb, resource, "Test", 1, 1);
|
|
13
14
|
tsfn.Release();
|
|
14
15
|
return info.Env().Undefined();
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
}
|
|
18
|
+
} // namespace
|
|
18
19
|
|
|
19
20
|
Object InitThreadSafeFunctionPtr(Env env) {
|
|
20
21
|
Object exports = Object::New(env);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
#include "napi.h"
|
|
2
|
-
#include <thread>
|
|
3
|
-
#include <cstdlib>
|
|
4
1
|
#include <condition_variable>
|
|
2
|
+
#include <cstdlib>
|
|
5
3
|
#include <mutex>
|
|
4
|
+
#include <thread>
|
|
5
|
+
#include "napi.h"
|
|
6
6
|
|
|
7
7
|
#if (NAPI_VERSION > 3)
|
|
8
8
|
|
|
@@ -11,9 +11,8 @@ using namespace Napi;
|
|
|
11
11
|
namespace {
|
|
12
12
|
|
|
13
13
|
struct TestData {
|
|
14
|
+
TestData(Promise::Deferred&& deferred) : deferred(std::move(deferred)){};
|
|
14
15
|
|
|
15
|
-
TestData(Promise::Deferred&& deferred) : deferred(std::move(deferred)) {};
|
|
16
|
-
|
|
17
16
|
// Native Promise returned to JavaScript
|
|
18
17
|
Promise::Deferred deferred;
|
|
19
18
|
|
|
@@ -28,7 +27,7 @@ struct TestData {
|
|
|
28
27
|
size_t expected_calls = 0;
|
|
29
28
|
};
|
|
30
29
|
|
|
31
|
-
void FinalizerCallback(Napi::Env env, TestData* finalizeData){
|
|
30
|
+
void FinalizerCallback(Napi::Env env, TestData* finalizeData) {
|
|
32
31
|
for (size_t i = 0; i < finalizeData->threads.size(); ++i) {
|
|
33
32
|
finalizeData->threads[i].join();
|
|
34
33
|
}
|
|
@@ -42,8 +41,8 @@ void FinalizerCallback(Napi::Env env, TestData* finalizeData){
|
|
|
42
41
|
|
|
43
42
|
void entryWithTSFN(ThreadSafeFunction tsfn, int threadId) {
|
|
44
43
|
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 100 + 1));
|
|
45
|
-
tsfn.BlockingCall(
|
|
46
|
-
callback.Call(
|
|
44
|
+
tsfn.BlockingCall([=](Napi::Env env, Function callback) {
|
|
45
|
+
callback.Call({Number::New(env, static_cast<double>(threadId))});
|
|
47
46
|
});
|
|
48
47
|
tsfn.Release();
|
|
49
48
|
}
|
|
@@ -54,15 +53,20 @@ static Value TestWithTSFN(const CallbackInfo& info) {
|
|
|
54
53
|
|
|
55
54
|
// We pass the test data to the Finalizer for cleanup. The finalizer is
|
|
56
55
|
// responsible for deleting this data as well.
|
|
57
|
-
TestData
|
|
56
|
+
TestData* testData = new TestData(Promise::Deferred::New(info.Env()));
|
|
58
57
|
|
|
59
58
|
ThreadSafeFunction tsfn = ThreadSafeFunction::New(
|
|
60
|
-
info.Env(),
|
|
61
|
-
|
|
59
|
+
info.Env(),
|
|
60
|
+
cb,
|
|
61
|
+
"Test",
|
|
62
|
+
0,
|
|
63
|
+
threadCount,
|
|
64
|
+
std::function<decltype(FinalizerCallback)>(FinalizerCallback),
|
|
65
|
+
testData);
|
|
62
66
|
|
|
63
67
|
for (int i = 0; i < threadCount; ++i) {
|
|
64
68
|
// A copy of the ThreadSafeFunction will go to the thread entry point
|
|
65
|
-
testData->threads.push_back(
|
|
69
|
+
testData->threads.push_back(std::thread(entryWithTSFN, tsfn, i));
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
return testData->deferred.Promise();
|
|
@@ -70,7 +74,7 @@ static Value TestWithTSFN(const CallbackInfo& info) {
|
|
|
70
74
|
|
|
71
75
|
// Task instance created for each new std::thread
|
|
72
76
|
class DelayedTSFNTask {
|
|
73
|
-
public:
|
|
77
|
+
public:
|
|
74
78
|
// Each instance has its own tsfn
|
|
75
79
|
ThreadSafeFunction tsfn;
|
|
76
80
|
|
|
@@ -90,8 +94,7 @@ public:
|
|
|
90
94
|
};
|
|
91
95
|
|
|
92
96
|
struct TestDataDelayed {
|
|
93
|
-
|
|
94
|
-
TestDataDelayed(Promise::Deferred &&deferred)
|
|
97
|
+
TestDataDelayed(Promise::Deferred&& deferred)
|
|
95
98
|
: deferred(std::move(deferred)){};
|
|
96
99
|
~TestDataDelayed() { taskInsts.clear(); };
|
|
97
100
|
// Native Promise returned to JavaScript
|
|
@@ -107,7 +110,7 @@ struct TestDataDelayed {
|
|
|
107
110
|
ThreadSafeFunction tsfn = ThreadSafeFunction();
|
|
108
111
|
};
|
|
109
112
|
|
|
110
|
-
void FinalizerCallbackDelayed(Napi::Env env, TestDataDelayed
|
|
113
|
+
void FinalizerCallbackDelayed(Napi::Env env, TestDataDelayed* finalizeData) {
|
|
111
114
|
for (size_t i = 0; i < finalizeData->threads.size(); ++i) {
|
|
112
115
|
finalizeData->threads[i].join();
|
|
113
116
|
}
|
|
@@ -115,15 +118,19 @@ void FinalizerCallbackDelayed(Napi::Env env, TestDataDelayed *finalizeData) {
|
|
|
115
118
|
delete finalizeData;
|
|
116
119
|
}
|
|
117
120
|
|
|
118
|
-
static Value TestDelayedTSFN(const CallbackInfo
|
|
121
|
+
static Value TestDelayedTSFN(const CallbackInfo& info) {
|
|
119
122
|
int threadCount = info[0].As<Number>().Int32Value();
|
|
120
123
|
Function cb = info[1].As<Function>();
|
|
121
124
|
|
|
122
|
-
TestDataDelayed
|
|
125
|
+
TestDataDelayed* testData =
|
|
123
126
|
new TestDataDelayed(Promise::Deferred::New(info.Env()));
|
|
124
127
|
|
|
125
128
|
testData->tsfn =
|
|
126
|
-
ThreadSafeFunction::New(info.Env(),
|
|
129
|
+
ThreadSafeFunction::New(info.Env(),
|
|
130
|
+
cb,
|
|
131
|
+
"Test",
|
|
132
|
+
0,
|
|
133
|
+
threadCount,
|
|
127
134
|
std::function<decltype(FinalizerCallbackDelayed)>(
|
|
128
135
|
FinalizerCallbackDelayed),
|
|
129
136
|
testData);
|
|
@@ -137,7 +144,7 @@ static Value TestDelayedTSFN(const CallbackInfo &info) {
|
|
|
137
144
|
}
|
|
138
145
|
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 100 + 1));
|
|
139
146
|
|
|
140
|
-
for (auto
|
|
147
|
+
for (auto& task : testData->taskInsts) {
|
|
141
148
|
std::lock_guard<std::mutex> lk(task->mtx);
|
|
142
149
|
task->tsfn = testData->tsfn;
|
|
143
150
|
task->cv.notify_all();
|
|
@@ -149,7 +156,7 @@ static Value TestDelayedTSFN(const CallbackInfo &info) {
|
|
|
149
156
|
void AcquireFinalizerCallback(Napi::Env env,
|
|
150
157
|
TestData* finalizeData,
|
|
151
158
|
TestData* context) {
|
|
152
|
-
(void)
|
|
159
|
+
(void)context;
|
|
153
160
|
for (size_t i = 0; i < finalizeData->threads.size(); ++i) {
|
|
154
161
|
finalizeData->threads[i].join();
|
|
155
162
|
}
|
|
@@ -161,13 +168,13 @@ void entryAcquire(ThreadSafeFunction tsfn, int threadId) {
|
|
|
161
168
|
tsfn.Acquire();
|
|
162
169
|
TestData* testData = tsfn.GetContext();
|
|
163
170
|
std::this_thread::sleep_for(std::chrono::milliseconds(std::rand() % 100 + 1));
|
|
164
|
-
tsfn.BlockingCall(
|
|
171
|
+
tsfn.BlockingCall([=](Napi::Env env, Function callback) {
|
|
165
172
|
// This lambda runs on the main thread so it's OK to access the variables
|
|
166
173
|
// `expected_calls` and `mainWantsRelease`.
|
|
167
174
|
testData->expected_calls--;
|
|
168
175
|
if (testData->expected_calls == 0 && testData->mainWantsRelease)
|
|
169
176
|
testData->tsfn.Release();
|
|
170
|
-
callback.Call(
|
|
177
|
+
callback.Call({Number::New(env, static_cast<double>(threadId))});
|
|
171
178
|
});
|
|
172
179
|
tsfn.Release();
|
|
173
180
|
}
|
|
@@ -182,7 +189,7 @@ static Value CreateThread(const CallbackInfo& info) {
|
|
|
182
189
|
ThreadSafeFunction tsfn = testData->tsfn;
|
|
183
190
|
int threadId = testData->threads.size();
|
|
184
191
|
// A copy of the ThreadSafeFunction will go to the thread entry point
|
|
185
|
-
testData->threads.push_back(
|
|
192
|
+
testData->threads.push_back(std::thread(entryAcquire, tsfn, threadId));
|
|
186
193
|
return Number::New(info.Env(), threadId);
|
|
187
194
|
}
|
|
188
195
|
|
|
@@ -198,21 +205,29 @@ static Value TestAcquire(const CallbackInfo& info) {
|
|
|
198
205
|
|
|
199
206
|
// We pass the test data to the Finalizer for cleanup. The finalizer is
|
|
200
207
|
// responsible for deleting this data as well.
|
|
201
|
-
TestData
|
|
208
|
+
TestData* testData = new TestData(Promise::Deferred::New(info.Env()));
|
|
202
209
|
|
|
203
|
-
testData->tsfn =
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
210
|
+
testData->tsfn =
|
|
211
|
+
ThreadSafeFunction::New(env,
|
|
212
|
+
cb,
|
|
213
|
+
"Test",
|
|
214
|
+
0,
|
|
215
|
+
1,
|
|
216
|
+
testData,
|
|
217
|
+
std::function<decltype(AcquireFinalizerCallback)>(
|
|
218
|
+
AcquireFinalizerCallback),
|
|
219
|
+
testData);
|
|
207
220
|
|
|
208
221
|
Object result = Object::New(env);
|
|
209
|
-
result["createThread"] =
|
|
210
|
-
|
|
222
|
+
result["createThread"] =
|
|
223
|
+
Function::New(env, CreateThread, "createThread", testData);
|
|
224
|
+
result["stopThreads"] =
|
|
225
|
+
Function::New(env, StopThreads, "stopThreads", testData);
|
|
211
226
|
result["promise"] = testData->deferred.Promise();
|
|
212
227
|
|
|
213
228
|
return result;
|
|
214
229
|
}
|
|
215
|
-
}
|
|
230
|
+
} // namespace
|
|
216
231
|
|
|
217
232
|
Object InitThreadSafeFunctionSum(Env env) {
|
|
218
233
|
Object exports = Object::New(env);
|
|
@@ -33,15 +33,15 @@ module.exports = require('../common').runTest(test);
|
|
|
33
33
|
/** @param {number[]} N */
|
|
34
34
|
const sum = (N) => N.reduce((sum, n) => sum + n, 0);
|
|
35
35
|
|
|
36
|
-
function test(binding) {
|
|
37
|
-
async function check(bindingFunction) {
|
|
36
|
+
function test (binding) {
|
|
37
|
+
async function check (bindingFunction) {
|
|
38
38
|
const calls = [];
|
|
39
39
|
const result = await bindingFunction(THREAD_COUNT, Array.prototype.push.bind(calls));
|
|
40
40
|
assert.ok(result);
|
|
41
41
|
assert.equal(sum(calls), EXPECTED_SUM);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
async function checkAcquire() {
|
|
44
|
+
async function checkAcquire () {
|
|
45
45
|
const calls = [];
|
|
46
46
|
const { promise, createThread, stopThreads } = binding.threadsafe_function_sum.testAcquire(Array.prototype.push.bind(calls));
|
|
47
47
|
for (let i = 0; i < THREAD_COUNT; i++) {
|
|
@@ -15,27 +15,40 @@ static Value TestUnref(const CallbackInfo& info) {
|
|
|
15
15
|
Function setTimeout = MaybeUnwrap(global.Get("setTimeout")).As<Function>();
|
|
16
16
|
ThreadSafeFunction* tsfn = new ThreadSafeFunction;
|
|
17
17
|
|
|
18
|
-
*tsfn = ThreadSafeFunction::New(
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
*tsfn = ThreadSafeFunction::New(
|
|
19
|
+
info.Env(), cb, resource, "Test", 1, 1, [tsfn](Napi::Env /* env */) {
|
|
20
|
+
delete tsfn;
|
|
21
|
+
});
|
|
21
22
|
|
|
22
23
|
tsfn->BlockingCall();
|
|
23
24
|
|
|
24
|
-
setTimeout.Call(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
});
|
|
25
|
+
setTimeout.Call(
|
|
26
|
+
global,
|
|
27
|
+
{Function::New(
|
|
28
|
+
env, [tsfn](const CallbackInfo& info) { tsfn->Unref(info.Env()); }),
|
|
29
|
+
Number::New(env, 100)});
|
|
30
30
|
|
|
31
31
|
return info.Env().Undefined();
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
static Value TestRef(const CallbackInfo& info) {
|
|
35
|
+
Function cb = info[1].As<Function>();
|
|
36
|
+
|
|
37
|
+
auto tsfn = ThreadSafeFunction::New(info.Env(), cb, "testRes", 1, 1);
|
|
38
|
+
|
|
39
|
+
tsfn.BlockingCall();
|
|
40
|
+
tsfn.Unref(info.Env());
|
|
41
|
+
tsfn.Ref(info.Env());
|
|
42
|
+
|
|
43
|
+
return info.Env().Undefined();
|
|
34
44
|
}
|
|
35
45
|
|
|
46
|
+
} // namespace
|
|
47
|
+
|
|
36
48
|
Object InitThreadSafeFunctionUnref(Env env) {
|
|
37
49
|
Object exports = Object::New(env);
|
|
38
50
|
exports["testUnref"] = Function::New(env, TestUnref);
|
|
51
|
+
exports["testRef"] = Function::New(env, TestRef);
|
|
39
52
|
return exports;
|
|
40
53
|
}
|
|
41
54
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const assert = require('assert');
|
|
4
4
|
|
|
5
|
-
const isMainProcess = process.argv[1]
|
|
5
|
+
const isMainProcess = process.argv[1] !== __filename;
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* In order to test that the event loop exits even with an active TSFN, we need
|
|
@@ -11,43 +11,88 @@ const isMainProcess = process.argv[1] != __filename;
|
|
|
11
11
|
* - Child process: creates TSFN. Native module Unref's via setTimeout after some time but does NOT call Release.
|
|
12
12
|
*
|
|
13
13
|
* Main process should expect child process to exit.
|
|
14
|
+
*
|
|
15
|
+
* We also added a new test case for `Ref`. The idea being, if a TSFN is active, the event loop that it belongs to should not exit
|
|
16
|
+
* Our setup is similar to the test for the `Unref` case, with the difference being now we are expecting the child process to hang
|
|
14
17
|
*/
|
|
15
18
|
|
|
16
19
|
if (isMainProcess) {
|
|
17
20
|
module.exports = require('../common').runTestWithBindingPath(test);
|
|
18
21
|
} else {
|
|
19
|
-
|
|
22
|
+
const isTestingRef = (process.argv[3] === 'true');
|
|
23
|
+
|
|
24
|
+
if (isTestingRef) {
|
|
25
|
+
execTSFNRefTest(process.argv[2]);
|
|
26
|
+
} else {
|
|
27
|
+
execTSFNUnrefTest(process.argv[2]);
|
|
28
|
+
}
|
|
20
29
|
}
|
|
21
30
|
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
function testUnRefCallback (resolve, reject, bindingFile) {
|
|
32
|
+
const child = require('../napi_child').spawn(process.argv[0], [
|
|
33
|
+
'--expose-gc', __filename, bindingFile, false
|
|
34
|
+
], { stdio: 'inherit' });
|
|
35
|
+
|
|
36
|
+
let timeout = setTimeout(function () {
|
|
37
|
+
child.kill();
|
|
38
|
+
timeout = 0;
|
|
39
|
+
reject(new Error('Expected child to die'));
|
|
40
|
+
}, 5000);
|
|
41
|
+
|
|
42
|
+
child.on('error', (err) => {
|
|
43
|
+
clearTimeout(timeout);
|
|
44
|
+
timeout = 0;
|
|
45
|
+
reject(new Error(err));
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
child.on('close', (code) => {
|
|
49
|
+
if (timeout) clearTimeout(timeout);
|
|
50
|
+
assert.strictEqual(code, 0, 'Expected return value 0');
|
|
51
|
+
resolve();
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function testRefCallback (resolve, reject, bindingFile) {
|
|
56
|
+
const child = require('../napi_child').spawn(process.argv[0], [
|
|
57
|
+
'--expose-gc', __filename, bindingFile, true
|
|
58
|
+
], { stdio: 'inherit' });
|
|
59
|
+
|
|
60
|
+
let timeout = setTimeout(function () {
|
|
61
|
+
child.kill();
|
|
62
|
+
timeout = 0;
|
|
63
|
+
resolve();
|
|
64
|
+
}, 1000);
|
|
65
|
+
|
|
66
|
+
child.on('error', (err) => {
|
|
67
|
+
clearTimeout(timeout);
|
|
68
|
+
timeout = 0;
|
|
69
|
+
reject(new Error(err));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
child.on('close', (code) => {
|
|
73
|
+
if (timeout) clearTimeout(timeout);
|
|
74
|
+
|
|
75
|
+
reject(new Error('We expected Child to hang'));
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function test (bindingFile) {
|
|
80
|
+
// Main process
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
testUnRefCallback(resolve, reject, bindingFile);
|
|
83
|
+
}).then(() => {
|
|
25
84
|
return new Promise((resolve, reject) => {
|
|
26
|
-
|
|
27
|
-
'--expose-gc', __filename, bindingFile
|
|
28
|
-
], { stdio: 'inherit' });
|
|
29
|
-
|
|
30
|
-
let timeout = setTimeout( function() {
|
|
31
|
-
child.kill();
|
|
32
|
-
timeout = 0;
|
|
33
|
-
reject(new Error("Expected child to die"));
|
|
34
|
-
}, 5000);
|
|
35
|
-
|
|
36
|
-
child.on("error", (err) => {
|
|
37
|
-
clearTimeout(timeout);
|
|
38
|
-
timeout = 0;
|
|
39
|
-
reject(new Error(err));
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
child.on("close", (code) => {
|
|
43
|
-
if (timeout) clearTimeout(timeout);
|
|
44
|
-
assert.strictEqual(code, 0, "Expected return value 0");
|
|
45
|
-
resolve();
|
|
46
|
-
});
|
|
85
|
+
testRefCallback(resolve, reject, bindingFile);
|
|
47
86
|
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function execTSFNUnrefTest (bindingFile) {
|
|
91
|
+
const binding = require(bindingFile);
|
|
92
|
+
binding.threadsafe_function_unref.testUnref({}, () => { });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function execTSFNRefTest (bindingFile) {
|
|
96
|
+
const binding = require(bindingFile);
|
|
97
|
+
binding.threadsafe_function_unref.testRef({}, () => { });
|
|
53
98
|
}
|