diff --git a/src/env.cc b/src/env.cc index c32cf2ff080a2c..648742c92f1a4a 100644 --- a/src/env.cc +++ b/src/env.cc @@ -968,6 +968,7 @@ void Environment::Exit(int exit_code) { isolate(), stack_trace_limit(), StackTrace::kDetailed)); } if (is_main_thread()) { + set_can_call_into_js(false); stop_sub_worker_contexts(); DisposePlatform(); exit(exit_code); diff --git a/test/parallel/test-worker-nested-on-process-exit.js b/test/parallel/test-worker-nested-on-process-exit.js new file mode 100644 index 00000000000000..aa544fa3289a11 --- /dev/null +++ b/test/parallel/test-worker-nested-on-process-exit.js @@ -0,0 +1,20 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const { Worker, workerData } = require('worker_threads'); + +// Test that 'exit' events for nested Workers are not received when a Worker +// terminates itself through process.exit(). + +if (workerData === null) { + const nestedWorkerExitCounter = new Int32Array(new SharedArrayBuffer(4)); + const w = new Worker(__filename, { workerData: nestedWorkerExitCounter }); + w.on('exit', common.mustCall(() => { + assert.strictEqual(nestedWorkerExitCounter[0], 0); + })); +} else { + const nestedWorker = new Worker('setInterval(() => {}, 100)', { eval: true }); + // The counter should never be increased here. + nestedWorker.on('exit', () => workerData[0]++); + nestedWorker.on('online', () => process.exit()); +} diff --git a/test/parallel/test-worker-on-process-exit.js b/test/parallel/test-worker-on-process-exit.js new file mode 100644 index 00000000000000..ec1c4affd1cc6f --- /dev/null +++ b/test/parallel/test-worker-on-process-exit.js @@ -0,0 +1,22 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const { spawnSync } = require('child_process'); +const { Worker } = require('worker_threads'); + +// Test that 'exit' events for Workers are not received when the main thread +// terminates itself through process.exit(). + +if (process.argv[2] !== 'child') { + const { + stdout, stderr, status + } = spawnSync(process.execPath, [__filename, 'child'], { encoding: 'utf8' }); + assert.strictEqual(stderr, ''); + assert.strictEqual(stdout, ''); + assert.strictEqual(status, 0); +} else { + const nestedWorker = new Worker('setInterval(() => {}, 100)', { eval: true }); + // This console.log() should never fire. + nestedWorker.on('exit', () => console.log('exit event received')); + nestedWorker.on('online', () => process.exit()); +}