diff --git a/lib/internal/modules/esm/public_loader_proxy.js b/lib/internal/modules/esm/public_loader_proxy.js index 592484a376515b..1ca230a3d032ae 100644 --- a/lib/internal/modules/esm/public_loader_proxy.js +++ b/lib/internal/modules/esm/public_loader_proxy.js @@ -10,6 +10,8 @@ const commsChannel = new SharedArrayBuffer(2048); * The lock/unlock segment of the shared memory. Atomics require this to be a Int32Array. This * segment is used to tell the main to sleep when the worker is worker, and vice verse (for the * worker to sleep whilst the main is working). + * 0 → main sleeps + * 1 → worker sleeps */ const lock = new Int32Array(commsChannel, 0, 4); /** @@ -24,15 +26,15 @@ const worker = new Worker('./worker.js', { }); worker.unref(); // ! Allows the process to eventually exit when worker is in its final sleep. -Atomics.wait(lock, 0, 1); // ! Block this module until the worker is ready. +Atomics.wait(lock, 0, 0); // ! Block this module until the worker is ready. function makeRequest(type, data) { requestResponseData.fill(0); // Erase any previous request/response (it's already been handled) - Atomics.store(lock, 0, 1); // Send request to worker const request = serialize({ data, type }); requestResponseData.set(request); + Atomics.store(lock, 0, 0); // Send request to worker Atomics.notify(lock, 0); // Notify worker of new request - Atomics.wait(lock, 0, 1); // Sleep until worker responds + Atomics.wait(lock, 0, 0); // Sleep until worker responds return deserialize(requestResponseData); } diff --git a/lib/internal/modules/esm/worker.js b/lib/internal/modules/esm/worker.js index 4034e6e99ff9a8..1dccbd8bdd40d1 100644 --- a/lib/internal/modules/esm/worker.js +++ b/lib/internal/modules/esm/worker.js @@ -3,14 +3,13 @@ const { workerData } = require('internal/worker_threads'); const { deserialize, serialize } = require('v8'); const { commsChannel } = workerData; +// lock = 0 → main sleeps +// lock = 1 → worker sleeps const lock = new Int32Array(commsChannel, 0, 4); // Required by Atomics const requestResponseData = new Uint8Array(commsChannel, 4, 2044); // for TextEncoder/Decoder const publicESMLoader = new ESMLoader(); -Atomics.store(lock, 0, 0); // Send 'ready' signal to main -Atomics.notify(lock, 0); // Notify main of signal - const types = { 'addCustomLoaders': publicESMLoader.addCustomLoaders, 'cjsCache.delete': publicESMLoader.cjsCache.delete, @@ -21,13 +20,16 @@ const types = { 'resolve': publicESMLoader.resolve, }; +Atomics.store(lock, 0, 1); // Send 'ready' signal to main +Atomics.notify(lock, 0); // Notify main of signal + while (true) { // event loop - Atomics.wait(lock, 0, 0); // This pauses the while loop + Atomics.wait(lock, 0, 1); // This pauses the while loop // Worker is now active and main is sleeping const { data, type } = deserialize(requestResponseData); const response = await types[type](data); requestResponseData.fill(0); - Atomics.store(lock, 0, 0); // Send response to main requestResponseData.set(serialize(response)); + Atomics.store(lock, 0, 1); // Send response to main Atomics.notify(lock, 0); // Notify main of new response };