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.
Files changed (206) hide show
  1. package/CHANGELOG.md +25 -2
  2. package/doc/changelog.md +4 -0
  3. package/doc/index.rst +1 -2
  4. package/doc/types.md +3 -3
  5. package/package.json +5 -5
  6. package/src/cnoke/cnoke.js +40 -834
  7. package/src/cnoke/package.json +1 -0
  8. package/src/cnoke/src/builder.js +447 -0
  9. package/src/cnoke/src/index.js +20 -0
  10. package/src/cnoke/src/tools.js +401 -0
  11. package/src/core/libcc/libcc.cc +2 -2
  12. package/src/koffi/build/2.3.6-beta.1/koffi_darwin_arm64/koffi.node +0 -0
  13. package/src/koffi/build/2.3.6-beta.1/koffi_darwin_x64/koffi.node +0 -0
  14. package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_arm64/koffi.node +0 -0
  15. package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_ia32/koffi.node +0 -0
  16. package/src/koffi/build/2.3.6-beta.1/koffi_freebsd_x64/koffi.node +0 -0
  17. package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm32hf/koffi.node +0 -0
  18. package/src/koffi/build/2.3.6-beta.1/koffi_linux_arm64/koffi.node +0 -0
  19. package/src/koffi/build/2.3.6-beta.1/koffi_linux_ia32/koffi.node +0 -0
  20. package/src/koffi/build/2.3.6-beta.1/koffi_linux_riscv64hf64/koffi.node +0 -0
  21. package/src/koffi/build/2.3.6-beta.1/koffi_linux_x64/koffi.node +0 -0
  22. package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_ia32/koffi.node +0 -0
  23. package/src/koffi/build/2.3.6-beta.1/koffi_openbsd_x64/koffi.node +0 -0
  24. package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.exp +0 -0
  25. package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.lib +0 -0
  26. package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.node +0 -0
  27. package/src/koffi/build/2.3.6-beta.1/koffi_win32_arm64/koffi.pdb +0 -0
  28. package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.exp +0 -0
  29. package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.lib +0 -0
  30. package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.node +0 -0
  31. package/src/koffi/build/2.3.6-beta.1/koffi_win32_ia32/koffi.pdb +0 -0
  32. package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.exp +0 -0
  33. package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.lib +0 -0
  34. package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.node +0 -0
  35. package/src/koffi/build/2.3.6-beta.1/koffi_win32_x64/koffi.pdb +0 -0
  36. package/src/koffi/src/abi_arm32.cc +43 -14
  37. package/src/koffi/src/abi_arm64.cc +95 -21
  38. package/src/koffi/src/abi_riscv64.cc +125 -64
  39. package/src/koffi/src/abi_x64_sysv.cc +38 -20
  40. package/src/koffi/src/abi_x64_win.cc +11 -5
  41. package/src/koffi/src/abi_x86.cc +14 -7
  42. package/src/koffi/src/call.cc +114 -44
  43. package/src/koffi/src/call.hh +6 -4
  44. package/src/koffi/src/ffi.cc +172 -147
  45. package/src/koffi/src/ffi.hh +18 -10
  46. package/src/koffi/src/index.d.ts +28 -7
  47. package/src/koffi/src/index.js +23 -4
  48. package/src/koffi/src/util.cc +261 -69
  49. package/src/koffi/src/util.hh +34 -8
  50. package/vendor/node-addon-api/CHANGELOG.md +122 -9
  51. package/vendor/node-addon-api/CONTRIBUTING.md +10 -10
  52. package/vendor/node-addon-api/README.md +36 -12
  53. package/vendor/node-addon-api/benchmark/function_args.cc +95 -62
  54. package/vendor/node-addon-api/benchmark/function_args.js +6 -6
  55. package/vendor/node-addon-api/benchmark/index.js +1 -1
  56. package/vendor/node-addon-api/benchmark/property_descriptor.cc +27 -34
  57. package/vendor/node-addon-api/benchmark/property_descriptor.js +5 -4
  58. package/vendor/node-addon-api/doc/async_operations.md +1 -1
  59. package/vendor/node-addon-api/doc/async_worker_variants.md +23 -2
  60. package/vendor/node-addon-api/doc/cmake-js.md +1 -1
  61. package/vendor/node-addon-api/doc/error_handling.md +3 -3
  62. package/vendor/node-addon-api/doc/external.md +7 -0
  63. package/vendor/node-addon-api/doc/handle_scope.md +14 -0
  64. package/vendor/node-addon-api/doc/hierarchy.md +1 -1
  65. package/vendor/node-addon-api/doc/object.md +27 -0
  66. package/vendor/node-addon-api/index.js +3 -3
  67. package/vendor/node-addon-api/napi-inl.deprecated.h +121 -127
  68. package/vendor/node-addon-api/napi-inl.h +1178 -1144
  69. package/vendor/node-addon-api/napi.h +2786 -2675
  70. package/vendor/node-addon-api/package.json +42 -1
  71. package/vendor/node-addon-api/test/addon.cc +8 -6
  72. package/vendor/node-addon-api/test/addon_build/index.js +9 -9
  73. package/vendor/node-addon-api/test/addon_build/tpl/addon.cc +2 -1
  74. package/vendor/node-addon-api/test/addon_build/tpl/index.js +4 -4
  75. package/vendor/node-addon-api/test/addon_data.cc +12 -13
  76. package/vendor/node-addon-api/test/array_buffer.js +3 -2
  77. package/vendor/node-addon-api/test/async_progress_queue_worker.cc +13 -3
  78. package/vendor/node-addon-api/test/async_progress_queue_worker.js +5 -5
  79. package/vendor/node-addon-api/test/async_progress_worker.cc +65 -9
  80. package/vendor/node-addon-api/test/async_progress_worker.js +14 -9
  81. package/vendor/node-addon-api/test/async_worker.cc +236 -3
  82. package/vendor/node-addon-api/test/async_worker.js +122 -37
  83. package/vendor/node-addon-api/test/async_worker_nocallback.js +9 -3
  84. package/vendor/node-addon-api/test/async_worker_persistent.js +2 -2
  85. package/vendor/node-addon-api/test/basic_types/array.js +3 -4
  86. package/vendor/node-addon-api/test/basic_types/boolean.cc +4 -2
  87. package/vendor/node-addon-api/test/basic_types/boolean.js +1 -2
  88. package/vendor/node-addon-api/test/basic_types/number.cc +12 -6
  89. package/vendor/node-addon-api/test/basic_types/number.js +19 -18
  90. package/vendor/node-addon-api/test/basic_types/value.cc +52 -1
  91. package/vendor/node-addon-api/test/basic_types/value.js +44 -21
  92. package/vendor/node-addon-api/test/bigint.cc +2 -1
  93. package/vendor/node-addon-api/test/binding.cc +11 -5
  94. package/vendor/node-addon-api/test/binding.gyp +3 -1
  95. package/vendor/node-addon-api/test/buffer.cc +46 -38
  96. package/vendor/node-addon-api/test/buffer.js +12 -12
  97. package/vendor/node-addon-api/test/callbackInfo.cc +27 -0
  98. package/vendor/node-addon-api/test/callbackInfo.js +9 -0
  99. package/vendor/node-addon-api/test/callbackscope.cc +19 -2
  100. package/vendor/node-addon-api/test/callbackscope.js +20 -20
  101. package/vendor/node-addon-api/test/common/index.js +37 -4
  102. package/vendor/node-addon-api/test/dataview/dataview.js +5 -5
  103. package/vendor/node-addon-api/test/dataview/dataview_read_write.js +14 -12
  104. package/vendor/node-addon-api/test/date.cc +2 -1
  105. package/vendor/node-addon-api/test/date.js +2 -2
  106. package/vendor/node-addon-api/test/env_cleanup.cc +12 -0
  107. package/vendor/node-addon-api/test/env_cleanup.js +38 -39
  108. package/vendor/node-addon-api/test/error.cc +6 -5
  109. package/vendor/node-addon-api/test/error_terminating_environment.js +64 -60
  110. package/vendor/node-addon-api/test/external.cc +36 -32
  111. package/vendor/node-addon-api/test/external.js +43 -46
  112. package/vendor/node-addon-api/test/function.cc +58 -44
  113. package/vendor/node-addon-api/test/function.js +4 -0
  114. package/vendor/node-addon-api/test/function_reference.cc +15 -13
  115. package/vendor/node-addon-api/test/globalObject/global_object_delete_property.js +50 -53
  116. package/vendor/node-addon-api/test/globalObject/global_object_get_property.js +33 -34
  117. package/vendor/node-addon-api/test/globalObject/global_object_has_own_property.js +38 -40
  118. package/vendor/node-addon-api/test/globalObject/global_object_set_property.js +47 -49
  119. package/vendor/node-addon-api/test/handlescope.cc +29 -3
  120. package/vendor/node-addon-api/test/handlescope.js +5 -3
  121. package/vendor/node-addon-api/test/index.js +1 -5
  122. package/vendor/node-addon-api/test/maybe/check.cc +49 -3
  123. package/vendor/node-addon-api/test/maybe/index.js +19 -7
  124. package/vendor/node-addon-api/test/memory_management.cc +9 -8
  125. package/vendor/node-addon-api/test/memory_management.js +2 -2
  126. package/vendor/node-addon-api/test/movable_callbacks.js +2 -2
  127. package/vendor/node-addon-api/test/name.js +3 -3
  128. package/vendor/node-addon-api/test/napi_child.js +2 -2
  129. package/vendor/node-addon-api/test/object/delete_property.js +7 -7
  130. package/vendor/node-addon-api/test/object/finalizer.cc +13 -12
  131. package/vendor/node-addon-api/test/object/finalizer.js +2 -2
  132. package/vendor/node-addon-api/test/object/get_property.js +6 -6
  133. package/vendor/node-addon-api/test/object/has_own_property.js +3 -3
  134. package/vendor/node-addon-api/test/object/has_property.js +4 -4
  135. package/vendor/node-addon-api/test/object/object.cc +191 -111
  136. package/vendor/node-addon-api/test/object/object.js +53 -52
  137. package/vendor/node-addon-api/test/object/object_deprecated.cc +24 -20
  138. package/vendor/node-addon-api/test/object/object_deprecated.js +3 -8
  139. package/vendor/node-addon-api/test/object/object_freeze_seal.js +54 -54
  140. package/vendor/node-addon-api/test/object/object_type_tag.cc +39 -0
  141. package/vendor/node-addon-api/test/object/object_type_tag.js +55 -0
  142. package/vendor/node-addon-api/test/object/subscript_operator.js +2 -2
  143. package/vendor/node-addon-api/test/object_reference.js +100 -100
  144. package/vendor/node-addon-api/test/objectwrap.cc +41 -34
  145. package/vendor/node-addon-api/test/objectwrap.js +23 -19
  146. package/vendor/node-addon-api/test/objectwrap_constructor_exception.cc +5 -5
  147. package/vendor/node-addon-api/test/objectwrap_constructor_exception.js +1 -1
  148. package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.cc +7 -7
  149. package/vendor/node-addon-api/test/objectwrap_multiple_inheritance.js +1 -1
  150. package/vendor/node-addon-api/test/objectwrap_removewrap.js +24 -32
  151. package/vendor/node-addon-api/test/objectwrap_worker_thread.js +5 -4
  152. package/vendor/node-addon-api/test/promise.cc +7 -0
  153. package/vendor/node-addon-api/test/promise.js +3 -1
  154. package/vendor/node-addon-api/test/reference.cc +1 -1
  155. package/vendor/node-addon-api/test/reference.js +2 -2
  156. package/vendor/node-addon-api/test/run_script.cc +1 -1
  157. package/vendor/node-addon-api/test/symbol.js +59 -66
  158. package/vendor/node-addon-api/test/testUtil.js +6 -6
  159. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.cc +64 -29
  160. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function.js +71 -34
  161. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.cc +111 -19
  162. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ctx.js +2 -1
  163. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.cc +36 -26
  164. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_existing_tsfn.js +5 -5
  165. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.cc +3 -2
  166. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_ptr.js +1 -1
  167. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.cc +47 -32
  168. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_sum.js +3 -3
  169. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.cc +22 -9
  170. package/vendor/node-addon-api/test/threadsafe_function/threadsafe_function_unref.js +76 -31
  171. package/vendor/node-addon-api/test/thunking_manual.cc +61 -74
  172. package/vendor/node-addon-api/test/thunking_manual.js +6 -7
  173. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.cc +20 -20
  174. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function.js +19 -19
  175. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.cc +57 -5
  176. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ctx.js +2 -0
  177. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_existing_tsfn.js +5 -5
  178. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.cc +5 -1
  179. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_ptr.js +4 -3
  180. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_sum.js +3 -3
  181. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.cc +14 -0
  182. package/vendor/node-addon-api/test/typed_threadsafe_function/typed_threadsafe_function_unref.js +76 -31
  183. package/vendor/node-addon-api/test/typedarray-bigint.js +2 -2
  184. package/vendor/node-addon-api/test/typedarray.cc +263 -70
  185. package/vendor/node-addon-api/test/typedarray.js +44 -10
  186. package/vendor/node-addon-api/test/version_management.cc +16 -15
  187. package/vendor/node-addon-api/test/version_management.js +18 -20
  188. package/vendor/node-addon-api/tools/check-napi.js +13 -14
  189. package/vendor/node-addon-api/tools/conversion.js +161 -169
  190. package/vendor/node-addon-api/tools/eslint-format.js +9 -1
  191. package/vendor/node-addon-api/unit-test/README.md +4 -4
  192. package/src/koffi/build/2.3.4/koffi_darwin_arm64.tar.gz +0 -0
  193. package/src/koffi/build/2.3.4/koffi_darwin_x64.tar.gz +0 -0
  194. package/src/koffi/build/2.3.4/koffi_freebsd_arm64.tar.gz +0 -0
  195. package/src/koffi/build/2.3.4/koffi_freebsd_ia32.tar.gz +0 -0
  196. package/src/koffi/build/2.3.4/koffi_freebsd_x64.tar.gz +0 -0
  197. package/src/koffi/build/2.3.4/koffi_linux_arm32hf.tar.gz +0 -0
  198. package/src/koffi/build/2.3.4/koffi_linux_arm64.tar.gz +0 -0
  199. package/src/koffi/build/2.3.4/koffi_linux_ia32.tar.gz +0 -0
  200. package/src/koffi/build/2.3.4/koffi_linux_riscv64hf64.tar.gz +0 -0
  201. package/src/koffi/build/2.3.4/koffi_linux_x64.tar.gz +0 -0
  202. package/src/koffi/build/2.3.4/koffi_openbsd_ia32.tar.gz +0 -0
  203. package/src/koffi/build/2.3.4/koffi_openbsd_x64.tar.gz +0 -0
  204. package/src/koffi/build/2.3.4/koffi_win32_arm64.tar.gz +0 -0
  205. package/src/koffi/build/2.3.4/koffi_win32_ia32.tar.gz +0 -0
  206. 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 &&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 *callData;
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 * /*finalizeData */, void *context) {
26
- TestContext *testContext = static_cast<TestContext *>(context);
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, napi_value /* callback */, void *context,
36
- void *data) {
37
- TestContext *testContext = static_cast<TestContext *>(context);
38
- testContext->callData = static_cast<double *>(data);
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, napi_value /* callback */, void *context,
47
- void * /*data*/) {
48
- TestContext *testContext = static_cast<TestContext *>(context);
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 &info) {
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 & /*info*/) {});
77
+ Function cb = Function::New(env, [](const CallbackInfo& /*info*/) {});
75
78
 
76
- TestContext *testContext = new TestContext(Napi::Promise::Deferred(env));
79
+ TestContext* testContext = new TestContext(Napi::Promise::Deferred(env));
77
80
 
78
- napi_status status = napi_create_threadsafe_function(
79
- env, cb, Object::New(env), String::New(env, "Test"), 0, 1,
80
- nullptr, /*finalize data*/
81
- FinalizeCB, testContext, hasData ? CallJSWithData : CallJSNoData,
82
- &testContext->tsfn);
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 *>(new double(std::rand())));
101
+ wrapped.BlockingCall(static_cast<void*>(new double(std::rand())));
92
102
  } else {
93
- wrapped.BlockingCall(static_cast<void *>(nullptr));
103
+ wrapped.BlockingCall(static_cast<void*>(nullptr));
94
104
  }
95
105
  } else {
96
106
  if (hasData) {
97
- wrapped.NonBlockingCall(static_cast<void *>(new double(std::rand())));
107
+ wrapped.NonBlockingCall(static_cast<void*>(new double(std::rand())));
98
108
  } else {
99
- wrapped.NonBlockingCall(static_cast<void *>(nullptr));
109
+ wrapped.NonBlockingCall(static_cast<void*>(nullptr));
100
110
  }
101
111
  }
102
112
 
103
113
  return testContext->deferred.Promise();
104
114
  }
105
115
 
106
- } // namespace
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, 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");
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 = ThreadSafeFunction::New(info.Env(), cb, resource, "Test", 1, 1);
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);
@@ -2,6 +2,6 @@
2
2
 
3
3
  module.exports = require('../common').runTest(test);
4
4
 
5
- function test(binding) {
5
+ function test (binding) {
6
6
  binding.threadsafe_function_ptr.test({}, () => {});
7
7
  }
@@ -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( [=](Napi::Env env, Function callback) {
46
- callback.Call( { Number::New(env, static_cast<double>(threadId))});
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 *testData = new TestData(Promise::Deferred::New(info.Env()));
56
+ TestData* testData = new TestData(Promise::Deferred::New(info.Env()));
58
57
 
59
58
  ThreadSafeFunction tsfn = ThreadSafeFunction::New(
60
- info.Env(), cb, "Test", 0, threadCount,
61
- std::function<decltype(FinalizerCallback)>(FinalizerCallback), testData);
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( std::thread(entryWithTSFN, tsfn, i) );
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 *finalizeData) {
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 &info) {
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 *testData =
125
+ TestDataDelayed* testData =
123
126
  new TestDataDelayed(Promise::Deferred::New(info.Env()));
124
127
 
125
128
  testData->tsfn =
126
- ThreadSafeFunction::New(info.Env(), cb, "Test", 0, threadCount,
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 &task : testData->taskInsts) {
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) context;
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( [=](Napi::Env env, Function callback) {
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( { Number::New(env, static_cast<double>(threadId))});
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( std::thread(entryAcquire, tsfn, threadId) );
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 *testData = new TestData(Promise::Deferred::New(info.Env()));
208
+ TestData* testData = new TestData(Promise::Deferred::New(info.Env()));
202
209
 
203
- testData->tsfn = ThreadSafeFunction::New(
204
- env, cb, "Test", 0, 1, testData,
205
- std::function<decltype(AcquireFinalizerCallback)>(AcquireFinalizerCallback),
206
- testData);
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"] = Function::New( env, CreateThread, "createThread", testData);
210
- result["stopThreads"] = Function::New( env, StopThreads, "stopThreads", testData);
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(info.Env(), cb, resource, "Test", 1, 1, [tsfn](Napi::Env /* env */) {
19
- delete tsfn;
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( global, {
25
- Function::New(env, [tsfn](const CallbackInfo& info) {
26
- tsfn->Unref(info.Env());
27
- }),
28
- Number::New(env, 100)
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] != __filename;
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
- test(process.argv[2]);
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 test(bindingFile) {
23
- if (isMainProcess) {
24
- // Main process
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
- const child = require('../napi_child').spawn(process.argv[0], [
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
- } else {
49
- // Child process
50
- const binding = require(bindingFile);
51
- binding.threadsafe_function_unref.testUnref({}, () => { });
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
  }