| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -478,7 +478,8 @@ typedef void (*napi_threadsafe_function_call_js)(napi_env env, | |||
| 478 | 478 | - `[in] env`: The environment to use for API calls, or `NULL` if the thread-safe | |
| 479 | 479 | function is being torn down and `data` may need to be freed. | |
| 480 | 480 | - `[in] js_callback`: The JavaScript function to call, or `NULL` if the | |
| 481 | - thread-safe function is being torn down and `data` may need to be freed. | ||
| 481 | + thread-safe function is being torn down and `data` may need to be freed. It may | ||
| 482 | + also be `NULL` if the thread-safe function was created without `js_callback`. | ||
| 482 | 483 | - `[in] context`: The optional data with which the thread-safe function was | |
| 483 | 484 | created. | |
| 484 | 485 | - `[in] data`: Data created by the secondary thread. It is the responsibility of | |
@@ -4657,6 +4658,10 @@ prevent the event loop from exiting. The APIs `napi_ref_threadsafe_function` and | |||
| 4657 | 4658 | <!-- YAML | |
| 4658 | 4659 | added: v10.6.0 | |
| 4659 | 4660 | napiVersion: 4 | |
| 4661 | + changes: | ||
| 4662 | + - version: v10.17.0 | ||
| 4663 | + pr-url: https://github.com/nodejs/node/pull/27791 | ||
| 4664 | + description: Made `func` parameter optional with custom `call_js_cb`. | ||
| 4660 | 4665 | --> | |
| 4661 | 4666 | ```C | |
| 4662 | 4667 | NAPI_EXTERN napi_status | |
@@ -4674,7 +4679,8 @@ napi_create_threadsafe_function(napi_env env, | |||
| 4674 | 4679 | ``` | |
| 4675 | 4680 | ||
| 4676 | 4681 | - `[in] env`: The environment that the API is invoked under. | |
| 4677 | - - `[in] func`: The JavaScript function to call from another thread. | ||
| 4682 | + - `[in] func`: An optional JavaScript function to call from another thread. | ||
| 4683 | + It must be provided if `NULL` is passed to `call_js_cb`. | ||
| 4678 | 4684 | - `[in] async_resource`: An optional object associated with the async work that | |
| 4679 | 4685 | will be passed to possible `async_hooks` [`init` hooks][]. | |
| 4680 | 4686 | - `[in] async_resource_name`: A JavaScript string to provide an identifier for | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -319,10 +319,14 @@ class ThreadSafeFunction : public node::AsyncResource { | |||
| 319 | 319 | "ERR_NAPI_TSFN_STOP_IDLE_LOOP", | |
| 320 | 320 | "Failed to stop the idle loop") == napi_ok); | |
| 321 | 321 | } else { | |
| 322 | - v8::Local<v8::Function> js_cb = | ||
| 322 | + napi_value js_callback = nullptr; | ||
| 323 | + if (!ref.IsEmpty()) { | ||
| 324 | + v8::Local<v8::Function> js_cb = | ||
| 323 | 325 | v8::Local<v8::Function>::New(env->isolate, ref); | |
| 326 | + js_callback = v8impl::JsValueFromV8LocalValue(js_cb); | ||
| 327 | + } | ||
| 324 | 328 | call_js_cb(env, | |
| 325 | - v8impl::JsValueFromV8LocalValue(js_cb), | ||
| 329 | + js_callback, | ||
| 326 | 330 | context, | |
| 327 | 331 | data); | |
| 328 | 332 | } | |
@@ -1014,15 +1018,18 @@ napi_create_threadsafe_function(napi_env env, | |||
| 1014 | 1018 | napi_threadsafe_function_call_js call_js_cb, | |
| 1015 | 1019 | napi_threadsafe_function* result) { | |
| 1016 | 1020 | CHECK_ENV(env); | |
| 1017 | - CHECK_ARG(env, func); | ||
| 1018 | 1021 | CHECK_ARG(env, async_resource_name); | |
| 1019 | 1022 | RETURN_STATUS_IF_FALSE(env, initial_thread_count > 0, napi_invalid_arg); | |
| 1020 | 1023 | CHECK_ARG(env, result); | |
| 1021 | 1024 | ||
| 1022 | 1025 | napi_status status = napi_ok; | |
| 1023 | 1026 | ||
| 1024 | 1027 | v8::Local<v8::Function> v8_func; | |
| 1025 | - CHECK_TO_FUNCTION(env, v8_func, func); | ||
| 1028 | + if (func == nullptr) { | ||
| 1029 | + CHECK_ARG(env, call_js_cb); | ||
| 1030 | + } else { | ||
| 1031 | + CHECK_TO_FUNCTION(env, v8_func, func); | ||
| 1032 | + } | ||
| 1026 | 1033 | ||
| 1027 | 1034 | v8::Local<v8::Context> v8_context = env->context(); | |
| 1028 | 1035 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -129,6 +129,19 @@ static void call_js(napi_env env, napi_value cb, void* hint, void* data) { | |||
| 129 | 129 | } | |
| 130 | 130 | } | |
| 131 | 131 | ||
| 132 | + static napi_ref alt_ref; | ||
| 133 | + // Getting the data into JS with the alternative referece | ||
| 134 | + static void call_ref(napi_env env, napi_value _, void* hint, void* data) { | ||
| 135 | + if (!(env == NULL || alt_ref == NULL)) { | ||
| 136 | + napi_value fn, argv, undefined; | ||
| 137 | + NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, alt_ref, &fn)); | ||
| 138 | + NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, *(int*)data, &argv)); | ||
| 139 | + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined)); | ||
| 140 | + NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, fn, 1, &argv, | ||
| 141 | + NULL)); | ||
| 142 | + } | ||
| 143 | + } | ||
| 144 | + | ||
| 132 | 145 | // Cleanup | |
| 133 | 146 | static napi_value StopThread(napi_env env, napi_callback_info info) { | |
| 134 | 147 | size_t argc = 2; | |
@@ -168,20 +181,31 @@ static void join_the_threads(napi_env env, void *data, void *hint) { | |||
| 168 | 181 | napi_call_function(env, undefined, js_cb, 0, NULL, NULL)); | |
| 169 | 182 | NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, | |
| 170 | 183 | the_hint->js_finalize_cb)); | |
| 184 | + if (alt_ref != NULL) { | ||
| 185 | + NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, alt_ref)); | ||
| 186 | + alt_ref = NULL; | ||
| 187 | + } | ||
| 171 | 188 | } | |
| 172 | 189 | ||
| 173 | 190 | static napi_value StartThreadInternal(napi_env env, | |
| 174 | 191 | napi_callback_info info, | |
| 175 | 192 | napi_threadsafe_function_call_js cb, | |
| 176 | - bool block_on_full) { | ||
| 193 | + bool block_on_full, | ||
| 194 | + bool alt_ref_js_cb) { | ||
| 195 | + | ||
| 177 | 196 | size_t argc = 4; | |
| 178 | 197 | napi_value argv[4]; | |
| 179 | 198 | ||
| 199 | + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); | ||
| 200 | + if (alt_ref_js_cb) { | ||
| 201 | + NAPI_CALL(env, napi_create_reference(env, argv[0], 1, &alt_ref)); | ||
| 202 | + argv[0] = NULL; | ||
| 203 | + } | ||
| 204 | + | ||
| 180 | 205 | ts_info.block_on_full = | |
| 181 | 206 | (block_on_full ? napi_tsfn_blocking : napi_tsfn_nonblocking); | |
| 182 | 207 | ||
| 183 | 208 | NAPI_ASSERT(env, (ts_fn == NULL), "Existing thread-safe function"); | |
| 184 | - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL)); | ||
| 185 | 209 | napi_value async_name; | |
| 186 | 210 | NAPI_CALL(env, napi_create_string_utf8(env, "N-API Thread-safe Function Test", | |
| 187 | 211 | NAPI_AUTO_LENGTH, &async_name)); | |
@@ -223,16 +247,24 @@ static napi_value Release(napi_env env, napi_callback_info info) { | |||
| 223 | 247 | ||
| 224 | 248 | // Startup | |
| 225 | 249 | static napi_value StartThread(napi_env env, napi_callback_info info) { | |
| 226 | - return StartThreadInternal(env, info, call_js, true); | ||
| 250 | + return StartThreadInternal(env, info, call_js, | ||
| 251 | + /** block_on_full */true, /** alt_ref_js_cb */false); | ||
| 227 | 252 | } | |
| 228 | 253 | ||
| 229 | 254 | static napi_value StartThreadNonblocking(napi_env env, | |
| 230 | 255 | napi_callback_info info) { | |
| 231 | - return StartThreadInternal(env, info, call_js, false); | ||
| 256 | + return StartThreadInternal(env, info, call_js, | ||
| 257 | + /** block_on_full */false, /** alt_ref_js_cb */false); | ||
| 232 | 258 | } | |
| 233 | 259 | ||
| 234 | 260 | static napi_value StartThreadNoNative(napi_env env, napi_callback_info info) { | |
| 235 | - return StartThreadInternal(env, info, NULL, true); | ||
| 261 | + return StartThreadInternal(env, info, NULL, | ||
| 262 | + /** block_on_full */true, /** alt_ref_js_cb */false); | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + static napi_value StartThreadNoJsFunc(napi_env env, napi_callback_info info) { | ||
| 266 | + return StartThreadInternal(env, info, call_ref, | ||
| 267 | + /** block_on_full */true, /** alt_ref_js_cb */true); | ||
| 236 | 268 | } | |
| 237 | 269 | ||
| 238 | 270 | // Module init | |
@@ -269,6 +301,7 @@ static napi_value Init(napi_env env, napi_value exports) { | |||
| 269 | 301 | DECLARE_NAPI_PROPERTY("StartThread", StartThread), | |
| 270 | 302 | DECLARE_NAPI_PROPERTY("StartThreadNoNative", StartThreadNoNative), | |
| 271 | 303 | DECLARE_NAPI_PROPERTY("StartThreadNonblocking", StartThreadNonblocking), | |
| 304 | + DECLARE_NAPI_PROPERTY("StartThreadNoJsFunc", StartThreadNoJsFunc), | ||
| 272 | 305 | DECLARE_NAPI_PROPERTY("StopThread", StopThread), | |
| 273 | 306 | DECLARE_NAPI_PROPERTY("Unref", Unref), | |
| 274 | 307 | DECLARE_NAPI_PROPERTY("Release", Release), | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -102,6 +102,17 @@ new Promise(function testWithoutJSMarshaller(resolve) { | |||
| 102 | 102 | })) | |
| 103 | 103 | .then((result) => assert.deepStrictEqual(result, expectedArray)) | |
| 104 | 104 | ||
| 105 | + // Start the thread in blocking mode, and assert that all values are passed. | ||
| 106 | + // Quit after it's done. | ||
| 107 | + // Doesn't pass the callback js function to napi_create_threadsafe_function. | ||
| 108 | + // Instead, use an alternative reference to get js function called. | ||
| 109 | + .then(() => testWithJSMarshaller({ | ||
| 110 | + threadStarter: 'StartThreadNoJsFunc', | ||
| 111 | + maxQueueSize: binding.MAX_QUEUE_SIZE, | ||
| 112 | + quitAfter: binding.ARRAY_LENGTH | ||
| 113 | + })) | ||
| 114 | + .then((result) => assert.deepStrictEqual(result, expectedArray)) | ||
| 115 | + | ||
| 105 | 116 | // Start the thread in blocking mode with an infinite queue, and assert that all | |
| 106 | 117 | // values are passed. Quit after it's done. | |
| 107 | 118 | .then(() => testWithJSMarshaller({ | |
| Back | FazBrowse Home | New Git URL |
0 commit comments