module: prevent main thread exiting before esm worker ends
Some checks are pending
Coverage Linux (without intl) / coverage-linux-without-intl (push) Waiting to run
Coverage Linux / coverage-linux (push) Waiting to run
Coverage Windows / coverage-windows (push) Waiting to run
Test and upload documentation to artifacts / build-docs (push) Waiting to run
Linters / lint-addon-docs (push) Waiting to run
Linters / lint-cpp (push) Waiting to run
Linters / format-cpp (push) Waiting to run
Linters / lint-js-and-md (push) Waiting to run
Linters / lint-py (push) Waiting to run
Linters / lint-yaml (push) Waiting to run
Linters / lint-sh (push) Waiting to run
Linters / lint-codeowners (push) Waiting to run
Linters / lint-pr-url (push) Waiting to run
Linters / lint-readme (push) Waiting to run
Notify on Push / Notify on Force Push on `main` (push) Waiting to run
Notify on Push / Notify on Push on `main` that lacks metadata (push) Waiting to run
Scorecard supply-chain security / Scorecard analysis (push) Waiting to run

PR-URL: https://github.com/nodejs/node/pull/56183
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
This commit is contained in:
Shima Ryuhei 2024-12-11 08:52:29 +09:00 committed by GitHub
parent a364ec1d1c
commit 2063245b1f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 2 deletions

View File

@ -215,8 +215,6 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) {
(port ?? syncCommPort).postMessage(wrapMessage('error', exception));
}
AtomicsAdd(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 1);
AtomicsNotify(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION);
if (shouldRemoveGlobalErrorHandler) {
process.off('uncaughtException', errorHandler);
}
@ -225,6 +223,10 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) {
// We keep checking for new messages to not miss any.
clearImmediate(immediate);
immediate = setImmediate(checkForMessages).unref();
// To prevent the main thread from terminating before this function completes after unlocking,
// the following process is executed at the end of the function.
AtomicsAdd(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 1);
AtomicsNotify(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION);
}
}

View File

@ -285,4 +285,20 @@ describe('Loader hooks parsing modules', { concurrency: !process.env.TEST_PARALL
assert.strictEqual(code, 0);
assert.strictEqual(signal, null);
});
it('throw maximum call stack error on the loader', async () => {
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
'--no-warnings',
'--experimental-loader',
fixtures.fileURL('/es-module-loaders/hooks-custom.mjs'),
'--input-type=module',
'--eval',
'await import("esmHook/maximumCallStack.mjs")',
]);
assert(stderr.includes('Maximum call stack size exceeded'));
assert.strictEqual(stdout, '');
assert.strictEqual(code, 1);
assert.strictEqual(signal, null);
});
});

View File

@ -105,5 +105,12 @@ export function load(url, context, next) {
};
}
if (url.endsWith('esmHook/maximumCallStack.mjs')) {
function recurse() {
recurse();
}
recurse();
}
return next(url);
}