mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
esm: propagate process.exit from the loader thread to the main thread
PR-URL: https://github.com/nodejs/node/pull/47548 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
This commit is contained in:
@@ -504,6 +504,7 @@ class HooksProxy {
|
||||
},
|
||||
});
|
||||
this.#worker.unref(); // ! Allows the process to eventually exit.
|
||||
this.#worker.on('exit', process.exit);
|
||||
}
|
||||
|
||||
#waitForWorker() {
|
||||
@@ -513,6 +514,7 @@ class HooksProxy {
|
||||
debug('wait for signal from worker');
|
||||
AtomicsWait(this.#lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 0);
|
||||
const response = this.#worker.receiveMessageSync();
|
||||
if (response.message.status === 'exit') { return; }
|
||||
const { preloadScripts } = this.#unwrapMessage(response);
|
||||
this.#executePreloadScripts(preloadScripts);
|
||||
}
|
||||
@@ -593,6 +595,8 @@ class HooksProxy {
|
||||
debug('got sync response from worker', { method, args });
|
||||
if (response.message.status === 'never-settle') {
|
||||
process.exit(kUnfinishedTopLevelAwait);
|
||||
} else if (response.message.status === 'exit') {
|
||||
process.exit(response.message.body);
|
||||
}
|
||||
return this.#unwrapMessage(response);
|
||||
}
|
||||
|
||||
@@ -66,6 +66,19 @@ async function customizedModuleWorker(lock, syncCommPort, errorHandler) {
|
||||
let hooks, preloadScripts, initializationError;
|
||||
let hasInitializationError = false;
|
||||
|
||||
{
|
||||
// If a custom hook is calling `process.exit`, we should wake up the main thread
|
||||
// so it can detect the exit event.
|
||||
const { exit } = process;
|
||||
process.exit = function(code) {
|
||||
syncCommPort.postMessage(wrapMessage('exit', code ?? process.exitCode));
|
||||
AtomicsAdd(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION, 1);
|
||||
AtomicsNotify(lock, WORKER_TO_MAIN_THREAD_NOTIFICATION);
|
||||
return ReflectApply(exit, this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
initializeESM();
|
||||
const initResult = await initializeHooks();
|
||||
|
||||
@@ -195,4 +195,52 @@ describe('Loader hooks', { concurrency: true }, () => {
|
||||
assert.strictEqual(code, 0);
|
||||
assert.strictEqual(signal, null);
|
||||
});
|
||||
|
||||
it('should be fine to call `process.exit` from a custom async hook', async () => {
|
||||
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
|
||||
'--no-warnings',
|
||||
'--experimental-import-meta-resolve',
|
||||
'--experimental-loader',
|
||||
'data:text/javascript,export function load(a,b,next){if(a==="data:exit")process.exit(42);return next(a,b)}',
|
||||
'--input-type=module',
|
||||
'--eval',
|
||||
'import "data:exit"',
|
||||
]);
|
||||
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(code, 42);
|
||||
assert.strictEqual(signal, null);
|
||||
});
|
||||
|
||||
it('should be fine to call `process.exit` from a custom sync hook', async () => {
|
||||
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
|
||||
'--no-warnings',
|
||||
'--experimental-import-meta-resolve',
|
||||
'--experimental-loader',
|
||||
'data:text/javascript,export function resolve(a,b,next){if(a==="exit:")process.exit(42);return next(a,b)}',
|
||||
'--input-type=module',
|
||||
'--eval',
|
||||
'import "data:text/javascript,import.meta.resolve(%22exit:%22)"',
|
||||
]);
|
||||
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(code, 42);
|
||||
assert.strictEqual(signal, null);
|
||||
});
|
||||
|
||||
it('should be fine to call `process.exit` from the loader thread top-level', async () => {
|
||||
const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [
|
||||
'--no-warnings',
|
||||
'--experimental-loader',
|
||||
'data:text/javascript,process.exit(42)',
|
||||
fixtures.path('empty.js'),
|
||||
]);
|
||||
|
||||
assert.strictEqual(stderr, '');
|
||||
assert.strictEqual(stdout, '');
|
||||
assert.strictEqual(code, 42);
|
||||
assert.strictEqual(signal, null);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user