-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
process: split bootstrappers by threads that can run them
This patch split part of the bootstrappers into three files: - `lib/internal/process/main_thread_only.js`: contains bootstrappers that can only be run in the main thread, including - `setupStdio` for the main thread that sets up `process.stdin`, `process.stdout`, `process.error` that may interact with external resources, e.g. TTY/File/Pipe/TCP sockets - `setupProcessMethods` that setup methods changing process-global states, e.g. `process.chdir`, `process.umask`, `process.setuid` - `setupSignalHandlers` - `setupChildProcessIpcChannel` that setup `process.send` for child processes. - `lib/internal/process/worker_thread_only.js`: contains bootstrappers that can only be run in the worker threads, including - `setupStdio` for the worker thread that are streams to be manipulated or piped to the parent thread - `lib/internal/process/per_thread.js`: contains bootstrappers that can be run in all threads, including: - `setupAssert` for `process.assert` - `setupCpuUsage` for `process.cpuUsage` - `setupHrtime` for `process.hrtime` and `process.hrtime.bigint` - `setupMemoryUsage` for `process.memoryUsage` - `setupConfig` for `process.config` - `setupKillAndExit` for `process.kill` and `process.exit` - `setupRawDebug` for `process._rawDebug` - `setupUncaughtExceptionCapture` for `process.setUncaughtExceptionCaptureCallback` and `process.hasUncaughtExceptionCaptureCallback` Hopefully in the future we can sort more bootstrappers in `boostrap/node.js` into these three files and further group them into functions that can be run before creating the snapshot / after loading the snapshot. This patch also moves most of the `isMainThread` conditionals into the main bootstrapper instead of letting them scattered around special-casing different implementations. PR-URL: #21378 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Backport-PR-URL: #21866 Reviewed-By: Michaël Zasso <targos@protonmail.com>
- Loading branch information
1 parent
eef975e
commit 581390c
Showing
7 changed files
with
227 additions
and
165 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
'use strict'; | ||
|
||
// This file contains process bootstrappers that can only be | ||
// run in the main thread | ||
|
||
const { | ||
errnoException | ||
} = require('internal/errors'); | ||
|
||
const { | ||
setupProcessStdio, | ||
getMainThreadStdio | ||
} = require('internal/process/stdio'); | ||
|
||
const assert = require('assert').strict; | ||
|
||
function setupStdio() { | ||
setupProcessStdio(getMainThreadStdio()); | ||
} | ||
|
||
// Non-POSIX platforms like Windows don't have certain methods. | ||
// Workers also lack these methods since they change process-global state. | ||
function setupProcessMethods(_chdir, _umask, _initgroups, _setegid, | ||
_seteuid, _setgid, _setuid, _setgroups) { | ||
if (_setgid !== undefined) { | ||
setupPosixMethods(_initgroups, _setegid, _seteuid, | ||
_setgid, _setuid, _setgroups); | ||
} | ||
|
||
process.chdir = function chdir(...args) { | ||
return _chdir(...args); | ||
}; | ||
|
||
process.umask = function umask(...args) { | ||
return _umask(...args); | ||
}; | ||
} | ||
|
||
function setupPosixMethods(_initgroups, _setegid, _seteuid, | ||
_setgid, _setuid, _setgroups) { | ||
|
||
process.initgroups = function initgroups(...args) { | ||
return _initgroups(...args); | ||
}; | ||
|
||
process.setegid = function setegid(...args) { | ||
return _setegid(...args); | ||
}; | ||
|
||
process.seteuid = function seteuid(...args) { | ||
return _seteuid(...args); | ||
}; | ||
|
||
process.setgid = function setgid(...args) { | ||
return _setgid(...args); | ||
}; | ||
|
||
process.setuid = function setuid(...args) { | ||
return _setuid(...args); | ||
}; | ||
|
||
process.setgroups = function setgroups(...args) { | ||
return _setgroups(...args); | ||
}; | ||
} | ||
|
||
// Worker threads don't receive signals. | ||
function setupSignalHandlers() { | ||
const constants = process.binding('constants').os.signals; | ||
const signalWraps = Object.create(null); | ||
let Signal; | ||
|
||
function isSignal(event) { | ||
return typeof event === 'string' && constants[event] !== undefined; | ||
} | ||
|
||
// Detect presence of a listener for the special signal types | ||
process.on('newListener', function(type) { | ||
if (isSignal(type) && signalWraps[type] === undefined) { | ||
if (Signal === undefined) | ||
Signal = process.binding('signal_wrap').Signal; | ||
const wrap = new Signal(); | ||
|
||
wrap.unref(); | ||
|
||
wrap.onsignal = process.emit.bind(process, type, type); | ||
|
||
const signum = constants[type]; | ||
const err = wrap.start(signum); | ||
if (err) { | ||
wrap.close(); | ||
throw errnoException(err, 'uv_signal_start'); | ||
} | ||
|
||
signalWraps[type] = wrap; | ||
} | ||
}); | ||
|
||
process.on('removeListener', function(type) { | ||
if (signalWraps[type] !== undefined && this.listenerCount(type) === 0) { | ||
signalWraps[type].close(); | ||
delete signalWraps[type]; | ||
} | ||
}); | ||
} | ||
|
||
function setupChildProcessIpcChannel() { | ||
// If we were spawned with env NODE_CHANNEL_FD then load that up and | ||
// start parsing data from that stream. | ||
if (process.env.NODE_CHANNEL_FD) { | ||
const fd = parseInt(process.env.NODE_CHANNEL_FD, 10); | ||
assert(fd >= 0); | ||
|
||
// Make sure it's not accidentally inherited by child processes. | ||
delete process.env.NODE_CHANNEL_FD; | ||
|
||
require('child_process')._forkChild(fd); | ||
assert(process.send); | ||
} | ||
} | ||
|
||
module.exports = { | ||
setupStdio, | ||
setupProcessMethods, | ||
setupSignalHandlers, | ||
setupChildProcessIpcChannel | ||
}; |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.