From 5e0c12f0afc40973683e018d964709f5bdabaef3 Mon Sep 17 00:00:00 2001 From: webreflection Date: Thu, 12 Oct 2023 00:30:44 +0200 Subject: [PATCH] A better fix for the Atomics.wait with costrol value --- esm/channel.js | 2 +- esm/index.js | 24 ++++++++++++++++-------- package-lock.json | 32 ++++++++++++++++---------------- package.json | 8 ++++---- test/issue-26/worker.js | 8 ++++---- 5 files changed, 41 insertions(+), 33 deletions(-) diff --git a/esm/channel.js b/esm/channel.js index 3832aa5..7c978d3 100644 --- a/esm/channel.js +++ b/esm/channel.js @@ -1,5 +1,5 @@ // ⚠️ AUTOMATICALLY GENERATED - DO NOT CHANGE -export const CHANNEL = '8db0a6b1-4d79-4ecd-8b7a-7ea5c1811764'; +export const CHANNEL = '0d0ac1f5-3d55-4854-86ec-2e8653dd16d4'; export const MAIN = 'M' + CHANNEL; export const THREAD = 'T' + CHANNEL; diff --git a/esm/index.js b/esm/index.js index 6fcd4a1..d7edf95 100644 --- a/esm/index.js +++ b/esm/index.js @@ -78,7 +78,8 @@ const coincident = (self, {parse = JSON.parse, stringify = JSON.stringify, trans const id = uid++; // first contact: just ask for how big the buffer should be - let sb = new Int32Array(new SharedArrayBuffer(I32_BYTES)); + // the value would be stored at index [1] while [0] is just control + let sb = new Int32Array(new SharedArrayBuffer(I32_BYTES * 2)); // if a transfer list has been passed, drop it from args let transfer = []; @@ -101,10 +102,10 @@ const coincident = (self, {parse = JSON.parse, stringify = JSON.stringify, trans clearTimeout(deadlock); // commit transaction using the returned / needed buffer length - const length = sb[0]; + const length = sb[1]; // filter undefined results - if (length < 0) return; + if (!length) return; // calculate the needed ui16 bytes length to store the result string const bytes = UI16_BYTES * length; @@ -134,6 +135,7 @@ const coincident = (self, {parse = JSON.parse, stringify = JSON.stringify, trans self.addEventListener('message', async (event) => { // grub the very same library CHANNEL; ignore otherwise const details = event.data?.[CHANNEL]; + let error; if (isArray(details)) { // if early enough, avoid leaking data to other listeners event.stopImmediatePropagation(); @@ -146,27 +148,32 @@ const coincident = (self, {parse = JSON.parse, stringify = JSON.stringify, trans try { // await for result either sync or async and serialize it const result = await actions.get(action)(...args); - if (result === void 0) - sb[0] = -1; // @see https://github.com/WebReflection/coincident/issues/26 - else { + if (result !== void 0) { const serialized = stringify(transform ? transform(result) : result); // store the result for "the very next" event listener call results.set(id, serialized); // communicate the required SharedArrayBuffer length out of the // resulting serialized string - sb[0] = serialized.length; + sb[1] = serialized.length; } } + catch (_) { + error = _; + } finally { seppuku = false; } } // unknown action should be notified as missing on the main thread else { - throw new Error(`Unsupported action: ${action}`); + error = new Error(`Unsupported action: ${action}`); } + // unlock the wait lock later on + sb[0] = 1; } // no action means: get results out of the well known `id` + // wait lock automatically unlocked here as no `0` value would + // possibly ever land at index `0` else { const result = results.get(id); results.delete(id); @@ -176,6 +183,7 @@ const coincident = (self, {parse = JSON.parse, stringify = JSON.stringify, trans } // release te worker waiting either the length or the result notify(sb, 0); + if (error) throw error; } }); } diff --git a/package-lock.json b/package-lock.json index f51505a..a5f78c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,13 +14,13 @@ "ws": "8.14.2" }, "devDependencies": { - "@playwright/test": "^1.38.1", + "@playwright/test": "^1.39.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "ascjs": "^6.0.2", "c8": "^8.0.1", "rollup": "^4.0.2", - "static-handler": "^0.4.2", + "static-handler": "^0.4.3", "typescript": "^5.2.2", "uhtml": "^3.2.2" }, @@ -114,12 +114,12 @@ } }, "node_modules/@playwright/test": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.38.1.tgz", - "integrity": "sha512-NqRp8XMwj3AK+zKLbZShl0r/9wKgzqI/527bkptKXomtuo+dOjU9NdMASQ8DNC9z9zLOMbG53T4eihYr3XR+BQ==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", "dev": true, "dependencies": { - "playwright": "1.38.1" + "playwright": "1.39.0" }, "bin": { "playwright": "cli.js" @@ -975,12 +975,12 @@ } }, "node_modules/playwright": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.38.1.tgz", - "integrity": "sha512-oRMSJmZrOu1FP5iu3UrCx8JEFRIMxLDM0c/3o4bpzU5Tz97BypefWf7TuTNPWeCe279TPal5RtPPZ+9lW/Qkow==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", "dev": true, "dependencies": { - "playwright-core": "1.38.1" + "playwright-core": "1.39.0" }, "bin": { "playwright": "cli.js" @@ -993,9 +993,9 @@ } }, "node_modules/playwright-core": { - "version": "1.38.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.38.1.tgz", - "integrity": "sha512-tQqNFUKa3OfMf4b2jQ7aGLB8o9bS3bOY0yMEtldtC2+spf8QXG9zvXLTXUeRsoNuxEYMgLYR+NXfAa1rjKRcrg==", + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", "dev": true, "bin": { "playwright-core": "cli.js" @@ -1179,9 +1179,9 @@ } }, "node_modules/static-handler": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/static-handler/-/static-handler-0.4.2.tgz", - "integrity": "sha512-Szbk521mneb5npxg3SEyoufsHr2osAzxMy71W2zFCzLB8wLhHYvKUDCMkLY6imi+fIqkpfas3rzXGBQf99aeEA==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/static-handler/-/static-handler-0.4.3.tgz", + "integrity": "sha512-rHi6vtxW/kjC+L18cRVAICAp/ymTjyvZHCPXIrejrlVrRrNxrVGk9FNCg+rC9wM7SpZ9euyjsr7tNVtqpA2iLA==", "dev": true, "dependencies": { "mime-types": "^2.1.35" diff --git a/package.json b/package.json index 74c8b5a..d18366c 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,10 @@ "rollup:uhtml": "rollup --config rollup/uhtml.config.js", "rollup:window": "rollup --config rollup/window.config.js", "test": "c8 node test/index.js", - "test:integration": "static-handler --cors --coop --coep --corp . 2>/dev/null & SH_PID=$!; EXIT_CODE=0; playwright test test/ || EXIT_CODE=$?; kill $SH_PID 2>/dev/null; exit $EXIT_CODE", + "test:integration": "static-handler --coi . 2>/dev/null & SH_PID=$!; EXIT_CODE=0; playwright test test/ || EXIT_CODE=$?; kill $SH_PID 2>/dev/null; exit $EXIT_CODE", "test:server": "node test/server/main.cjs", "ts": "tsc -p .", - "server": "npx static-handler --cors --coop --coep --corp .", + "server": "npx static-handler --coi .", "size": "echo -e \"\\x1b[1mfile size\\x1b[0m\"; echo \"es $(cat es.js | brotli | wc -c)\"; echo \"structured $(cat structured.js | brotli | wc -c)\"; echo \"window $(cat window.js | brotli | wc -c)\"; echo \"server $(cat server.js | brotli | wc -c)\"; echo \"uhtml $(cat uhtml.js | brotli | wc -c)\";", "coverage": "mkdir -p ./coverage; c8 report --reporter=text-lcov > ./coverage/lcov.info" }, @@ -29,13 +29,13 @@ "author": "Andrea Giammarchi", "license": "ISC", "devDependencies": { - "@playwright/test": "^1.38.1", + "@playwright/test": "^1.39.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-terser": "^0.4.4", "ascjs": "^6.0.2", "c8": "^8.0.1", "rollup": "^4.0.2", - "static-handler": "^0.4.2", + "static-handler": "^0.4.3", "typescript": "^5.2.2", "uhtml": "^3.2.2" }, diff --git a/test/issue-26/worker.js b/test/issue-26/worker.js index 314f46e..7c37e69 100644 --- a/test/issue-26/worker.js +++ b/test/issue-26/worker.js @@ -3,7 +3,7 @@ console.log('worker.js'); import coincident from '../../es.js'; const proxy = coincident(self); -(async () => { - for (let i = 0; i < 100000; i++) - proxy.func(); -})(); +for (let i = 0; i < 100000; i++) + proxy.func(); + +console.log('DONE');