From 2af12f49a81c3629f54446ac3c4ac84dd58e7016 Mon Sep 17 00:00:00 2001 From: Don Isaac Date: Wed, 8 Jan 2025 10:46:58 -0600 Subject: [PATCH 1/2] fix: node parallel test check in test runner (#16232) --- scripts/runner.node.mjs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/scripts/runner.node.mjs b/scripts/runner.node.mjs index 969ea1e5dbeeec..c20fe83dd9b20b 100755 --- a/scripts/runner.node.mjs +++ b/scripts/runner.node.mjs @@ -246,7 +246,7 @@ async function runTests() { if (!failedResults.length) { for (const testPath of tests) { const title = relative(cwd, join(testsPath, testPath)).replace(/\\/g, "/"); - if (title.startsWith("test/js/node/test/parallel/")) { + if (isNodeParallelTest(testPath)) { await runTest(title, async () => { const { ok, error, stdout } = await spawnBun(execPath, { cwd: cwd, @@ -850,12 +850,20 @@ function isJavaScriptTest(path) { return isJavaScript(path) && /\.test|spec\./.test(basename(path)); } +/** + * @param {string} testPath + * @returns {boolean} + */ +function isNodeParallelTest(testPath) { + return testPath.replaceAll(sep, "/").includes("js/node/test/parallel/") +} + /** * @param {string} path * @returns {boolean} */ function isTest(path) { - if (path.replaceAll(sep, "/").startsWith("js/node/test/parallel/") && targetDoesRunNodeTests()) return true; + if (isNodeParallelTest(path) && targetDoesRunNodeTests()) return true; if (path.replaceAll(sep, "/").startsWith("js/node/cluster/test-") && path.endsWith(".ts")) return true; return isTestStrict(path); } @@ -1035,7 +1043,7 @@ function getRelevantTests(cwd) { const filteredTests = []; if (options["node-tests"]) { - tests = tests.filter(testPath => testPath.includes("js/node/test/parallel/")); + tests = tests.filter(isNodeParallelTest); } const isMatch = (testPath, filter) => { From 043cb7fc5bf3cc877936fb3a10c47ab88f89d9ae Mon Sep 17 00:00:00 2001 From: Michael Jonker Date: Wed, 8 Jan 2025 18:47:46 +0000 Subject: [PATCH 2/2] Add documentation for threadsafe option in FFI JSCallback (#15982) Co-authored-by: Don Isaac --- docs/api/ffi.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/api/ffi.md b/docs/api/ffi.md index 6284689cb271b5..18fe2bb4391404 100644 --- a/docs/api/ffi.md +++ b/docs/api/ffi.md @@ -297,6 +297,20 @@ setTimeout(() => { When you're done with a JSCallback, you should call `close()` to free the memory. +### Experimental thread-safe callbacks +`JSCallback` has experimental support for thread-safe callbacks. This will be needed if you pass a callback function into a different thread from it's instantiation context. You can enable it with the optional `threadsafe` option flag. +```ts +const searchIterator = new JSCallback( + (ptr, length) => /hello/.test(new CString(ptr, length)), + { + returns: "bool", + args: ["ptr", "usize"], + threadsafe: true, // Optional. Defaults to `false` + }, +); +``` +Be aware that there are still cases where this does not 100% work. + {% callout %} **⚡️ Performance tip** — For a slight performance boost, directly pass `JSCallback.prototype.ptr` instead of the `JSCallback` object: