diff options
author | Anna Henningsen <anna@addaleax.net> | 2019-02-22 20:11:19 +0100 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-03-30 22:25:35 +0100 |
commit | 9fbf0c60b583dae3d34598352c3c7614118cd035 (patch) | |
tree | d615114117264cce1c469f2ff80088dfddf6149b /lib | |
parent | 1ee37aac09f263b00029561542cf3bea5db5113b (diff) | |
download | android-node-v8-9fbf0c60b583dae3d34598352c3c7614118cd035.tar.gz android-node-v8-9fbf0c60b583dae3d34598352c3c7614118cd035.tar.bz2 android-node-v8-9fbf0c60b583dae3d34598352c3c7614118cd035.zip |
worker: use copy of process.env
Instead of sharing the OS-backed store for all `process.env` instances,
create a copy of `process.env` for every worker that is created.
The copies do not interact. Native-addons do not see modifications to
`process.env` from Worker threads, but child processes started from
Workers do default to the Worker’s copy of `process.env`.
This makes Workers behave like child processes as far as `process.env`
is concerned, and an option corresponding to the `child_process`
module’s `env` option is added to the constructor.
Fixes: https://github.com/nodejs/node/issues/24947
PR-URL: https://github.com/nodejs/node/pull/26544
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Vse Mozhet Byt <vsemozhetbyt@gmail.com>
Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/worker.js | 24 | ||||
-rw-r--r-- | lib/worker_threads.js | 2 |
2 files changed, 26 insertions, 0 deletions
diff --git a/lib/internal/worker.js b/lib/internal/worker.js index 02f6661b54..c0a2baa869 100644 --- a/lib/internal/worker.js +++ b/lib/internal/worker.js @@ -45,6 +45,8 @@ const kOnCouldNotSerializeErr = Symbol('kOnCouldNotSerializeErr'); const kOnErrorMessage = Symbol('kOnErrorMessage'); const kParentSideStdio = Symbol('kParentSideStdio'); +const SHARE_ENV = Symbol.for('nodejs.worker_threads.SHARE_ENV'); + let debuglog; function debug(...args) { if (!debuglog) { @@ -79,12 +81,33 @@ class Worker extends EventEmitter { } } + let env; + if (typeof options.env === 'object' && options.env !== null) { + env = Object.create(null); + for (const [ key, value ] of Object.entries(options.env)) + env[key] = `${value}`; + } else if (options.env == null) { + env = process.env; + } else if (options.env !== SHARE_ENV) { + throw new ERR_INVALID_ARG_TYPE( + 'options.env', + ['object', 'undefined', 'null', 'worker_threads.SHARE_ENV'], + options.env); + } + const url = options.eval ? null : pathToFileURL(filename); // Set up the C++ handle for the worker, as well as some internal wiring. this[kHandle] = new WorkerImpl(url, options.execArgv); if (this[kHandle].invalidExecArgv) { throw new ERR_WORKER_INVALID_EXEC_ARGV(this[kHandle].invalidExecArgv); } + if (env === process.env) { + // This may be faster than manually cloning the object in C++, especially + // when recursively spawning Workers. + this[kHandle].cloneParentEnvVars(); + } else if (env !== undefined) { + this[kHandle].setEnvVars(env); + } this[kHandle].onexit = (code) => this[kOnExit](code); this[kPort] = this[kHandle].messagePort; this[kPort].on('message', (data) => this[kOnMessage](data)); @@ -253,6 +276,7 @@ function pipeWithoutWarning(source, dest) { module.exports = { ownsProcessState, isMainThread, + SHARE_ENV, threadId, Worker, }; diff --git a/lib/worker_threads.js b/lib/worker_threads.js index 722e47caf1..01d01e2a33 100644 --- a/lib/worker_threads.js +++ b/lib/worker_threads.js @@ -2,6 +2,7 @@ const { isMainThread, + SHARE_ENV, threadId, Worker } = require('internal/worker'); @@ -18,6 +19,7 @@ module.exports = { MessageChannel, moveMessagePortToContext, threadId, + SHARE_ENV, Worker, parentPort: null, workerData: null, |