From b020ac6adb5b6c3a1058d5ee2877f44da7aa0516 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 1 Feb 2019 06:27:04 -0800 Subject: [PATCH 1/2] worker: do not throw on property access or postMessage after termination. --- lib/internal/worker.js | 8 +++++ test/parallel/test-worker-safe-getters.js | 38 +++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 test/parallel/test-worker-safe-getters.js diff --git a/lib/internal/worker.js b/lib/internal/worker.js index 1640a9dd88a2ba..da663798148441 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -184,6 +184,8 @@ class Worker extends EventEmitter { } postMessage(...args) { + if (this[kPublicPort] === null) return; + this[kPublicPort].postMessage(...args); } @@ -219,14 +221,20 @@ class Worker extends EventEmitter { } get stdin() { + if (this[kParentSideStdio] === null) return null; + return this[kParentSideStdio].stdin; } get stdout() { + if (this[kParentSideStdio] === null) return null; + return this[kParentSideStdio].stdout; } get stderr() { + if (this[kParentSideStdio] === null) return null; + return this[kParentSideStdio].stderr; } } diff --git a/test/parallel/test-worker-safe-getters.js b/test/parallel/test-worker-safe-getters.js new file mode 100644 index 00000000000000..099fb8093ee3e1 --- /dev/null +++ b/test/parallel/test-worker-safe-getters.js @@ -0,0 +1,38 @@ +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const { Worker, isMainThread } = require('worker_threads'); + +if (isMainThread) { + const w = new Worker(__filename, { + stdin: true, + stdout: true, + stderr: true + }); + + w.on('exit', common.mustCall((code) => { + assert.strictEqual(code, 0); + + // `postMessage` should not throw after termination + // (this mimics the browser behavior). + assert.doesNotThrow(() => w.postMessage('foobar')); + assert.doesNotThrow(() => w.ref()); + assert.doesNotThrow(() => w.unref()); + + // Although not browser specific, probably wise to + // make sure the stream getters don't throw either. + assert.doesNotThrow(() => w.stdin); + assert.doesNotThrow(() => w.stdout); + assert.doesNotThrow(() => w.stderr); + + // Sanity check. + assert.strictEqual(w.threadId, -1); + assert.strictEqual(w.stdin, null); + assert.strictEqual(w.stdout, null); + assert.strictEqual(w.stderr, null); + })); +} else { + process.exit(0); +} From 8cdd3ec0c49df2da3531fbfb4247af17d43a7edd Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Fri, 1 Feb 2019 07:42:00 -0800 Subject: [PATCH 2/2] test: have parallel/test-worker-safe-getters.js abide by lint rules. --- test/parallel/test-worker-safe-getters.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/parallel/test-worker-safe-getters.js b/test/parallel/test-worker-safe-getters.js index 099fb8093ee3e1..23c8de7c7b0cfb 100644 --- a/test/parallel/test-worker-safe-getters.js +++ b/test/parallel/test-worker-safe-getters.js @@ -17,15 +17,15 @@ if (isMainThread) { // `postMessage` should not throw after termination // (this mimics the browser behavior). - assert.doesNotThrow(() => w.postMessage('foobar')); - assert.doesNotThrow(() => w.ref()); - assert.doesNotThrow(() => w.unref()); + w.postMessage('foobar'); + w.ref(); + w.unref(); // Although not browser specific, probably wise to // make sure the stream getters don't throw either. - assert.doesNotThrow(() => w.stdin); - assert.doesNotThrow(() => w.stdout); - assert.doesNotThrow(() => w.stderr); + w.stdin; + w.stdout; + w.stderr; // Sanity check. assert.strictEqual(w.threadId, -1);