From 4acd7f4390f4c73c14532fef1cb3e56911604935 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 29 Mar 2020 14:58:07 +0200 Subject: [PATCH] worker: do not emit 'exit' events during process.exit() Do not emit `'exit'` events caused by recursively stopping all running Workers from inside the `process.exit()` call. PR-URL: https://github.com/nodejs/node/pull/32546 Reviewed-By: Gireesh Punathil Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- src/env.cc | 1 + .../test-worker-nested-on-process-exit.js | 20 +++++++++++++++++ test/parallel/test-worker-on-process-exit.js | 22 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 test/parallel/test-worker-nested-on-process-exit.js create mode 100644 test/parallel/test-worker-on-process-exit.js diff --git a/src/env.cc b/src/env.cc index 5551f36c1249e0..7fb5116b3828c3 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()); +}