Skip to content

Commit 2ee3d81

Browse files
joyeecheungdanielleadams
authored andcommittedJan 3, 2023
bootstrap: merge main thread and worker thread initializations
Instead of doing the initializations of worker threads using small helper functions that are also used by the main thread initialization, wrap everything into a common prepareExecution() function with an isMainThread switch to turn off initializations that shouldn't be done for worker threads, so that we don't have to replicate all the initialization steps in the worker code, which can be error-prone. PR-URL: #44869 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 7b68c06 commit 2ee3d81

File tree

2 files changed

+71
-106
lines changed

2 files changed

+71
-106
lines changed
 

‎lib/internal/main/worker_thread.js

+10-52
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,8 @@ const {
1414
} = primordials;
1515

1616
const {
17-
patchProcessObject,
18-
setupCoverageHooks,
19-
setupInspectorHooks,
20-
setupWarningHandler,
21-
setupFetch,
22-
setupWebCrypto,
23-
setupCustomEvent,
24-
setupDebugEnv,
25-
setupPerfHooks,
26-
initializeDeprecations,
27-
initializeWASI,
28-
initializeCJSLoader,
29-
initializeESMLoader,
30-
initializeFrozenIntrinsics,
31-
initializeReport,
32-
initializeSourceMapsHandlers,
33-
loadPreloadModules,
34-
setupTraceCategoryState,
17+
prepareWorkerThreadExecution,
18+
setupUserModules,
3519
markBootstrapComplete
3620
} = require('internal/process/pre_execution');
3721

@@ -60,28 +44,13 @@ const {
6044
onGlobalUncaughtException
6145
} = require('internal/process/execution');
6246

63-
const publicWorker = require('worker_threads');
6447
let debug = require('internal/util/debuglog').debuglog('worker', (fn) => {
6548
debug = fn;
6649
});
6750

6851
const assert = require('internal/assert');
6952

70-
patchProcessObject();
71-
setupInspectorHooks();
72-
setupDebugEnv();
73-
74-
setupWarningHandler();
75-
setupFetch();
76-
setupWebCrypto();
77-
setupCustomEvent();
78-
initializeSourceMapsHandlers();
79-
80-
// Since worker threads cannot switch cwd, we do not need to
81-
// overwrite the process.env.NODE_V8_COVERAGE variable.
82-
if (process.env.NODE_V8_COVERAGE) {
83-
setupCoverageHooks(process.env.NODE_V8_COVERAGE);
84-
}
53+
prepareWorkerThreadExecution();
8554

8655
debug(`[${threadId}] is setting up worker child environment`);
8756

@@ -126,23 +95,11 @@ port.on('message', (message) => {
12695
hasStdin
12796
} = message;
12897

129-
setupTraceCategoryState();
130-
setupPerfHooks();
131-
initializeReport();
132-
if (manifestSrc) {
133-
require('internal/process/policy').setup(manifestSrc, manifestURL);
134-
}
135-
initializeDeprecations();
136-
initializeWASI();
137-
138-
require('internal/dns/utils').initializeDns();
139-
140-
initializeCJSLoader();
141-
initializeESMLoader();
142-
14398
if (argv !== undefined) {
14499
ArrayPrototypePushApply(process.argv, argv);
145100
}
101+
102+
const publicWorker = require('worker_threads');
146103
publicWorker.parentPort = publicPort;
147104
publicWorker.workerData = workerData;
148105

@@ -164,10 +121,10 @@ port.on('message', (message) => {
164121
};
165122
workerIo.sharedCwdCounter = cwdCounter;
166123

167-
const CJSLoader = require('internal/modules/cjs/loader');
168-
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
169-
loadPreloadModules();
170-
initializeFrozenIntrinsics();
124+
if (manifestSrc) {
125+
require('internal/process/policy').setup(manifestSrc, manifestURL);
126+
}
127+
setupUserModules();
171128

172129
if (!hasStdin)
173130
process.stdin.push(null);
@@ -198,6 +155,7 @@ port.on('message', (message) => {
198155
// runMain here might be monkey-patched by users in --require.
199156
// XXX: the monkey-patchability here should probably be deprecated.
200157
ArrayPrototypeSplice(process.argv, 1, 0, filename);
158+
const CJSLoader = require('internal/modules/cjs/loader');
201159
CJSLoader.Module.runMain(filename);
202160
}
203161
} else if (message.type === STDIO_PAYLOAD) {

‎lib/internal/process/pre_execution.js

+61-54
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,26 @@ const {
3333
isBuildingSnapshot,
3434
} = require('v8').startupSnapshot;
3535

36-
function prepareMainThreadExecution(expandArgv1 = false,
37-
initialzeModules = true) {
38-
refreshRuntimeOptions();
36+
function prepareMainThreadExecution(expandArgv1 = false, initialzeModules = true) {
37+
prepareExecution({
38+
expandArgv1,
39+
initialzeModules,
40+
isMainThread: true
41+
});
42+
}
43+
44+
function prepareWorkerThreadExecution() {
45+
prepareExecution({
46+
expandArgv1: false,
47+
initialzeModules: false, // Will need to initialize it after policy setup
48+
isMainThread: false
49+
});
50+
}
3951

40-
// TODO(joyeecheung): this is also necessary for workers when they deserialize
41-
// this toggle from the snapshot.
52+
function prepareExecution(options) {
53+
const { expandArgv1, initialzeModules, isMainThread } = options;
54+
55+
refreshRuntimeOptions();
4256
reconnectZeroFillToggle();
4357

4458
// Patch the process object with legacy properties and normalizations
@@ -60,48 +74,57 @@ function prepareMainThreadExecution(expandArgv1 = false,
6074
}
6175

6276
setupDebugEnv();
63-
64-
// Print stack trace on `SIGINT` if option `--trace-sigint` presents.
65-
setupStacktracePrinterOnSigint();
66-
6777
// Process initial diagnostic reporting configuration, if present.
6878
initializeReport();
69-
initializeReportSignalHandlers(); // Main-thread-only.
70-
71-
initializeHeapSnapshotSignalHandlers();
72-
73-
// If the process is spawned with env NODE_CHANNEL_FD, it's probably
74-
// spawned by our child_process module, then initialize IPC.
75-
// This attaches some internal event listeners and creates:
76-
// process.send(), process.channel, process.connected,
77-
// process.disconnect().
78-
setupChildProcessIpcChannel();
79-
80-
// Load policy from disk and parse it.
81-
initializePolicy();
82-
83-
// If this is a worker in cluster mode, start up the communication
84-
// channel. This needs to be done before any user code gets executed
85-
// (including preload modules).
86-
initializeClusterIPC();
87-
8879
initializeSourceMapsHandlers();
8980
initializeDeprecations();
9081
initializeWASI();
91-
9282
require('internal/dns/utils').initializeDns();
9383

94-
require('internal/v8/startup_snapshot').runDeserializeCallbacks();
84+
if (isMainThread) {
85+
assert(internalBinding('worker').isMainThread);
86+
// Worker threads will get the manifest in the message handler.
87+
const policy = readPolicyFromDisk();
88+
if (policy) {
89+
require('internal/process/policy')
90+
.setup(policy.manifestSrc, policy.manifestURL);
91+
}
9592

96-
if (!initialzeModules) {
97-
return;
93+
// Print stack trace on `SIGINT` if option `--trace-sigint` presents.
94+
setupStacktracePrinterOnSigint();
95+
initializeReportSignalHandlers(); // Main-thread-only.
96+
initializeHeapSnapshotSignalHandlers();
97+
// If the process is spawned with env NODE_CHANNEL_FD, it's probably
98+
// spawned by our child_process module, then initialize IPC.
99+
// This attaches some internal event listeners and creates:
100+
// process.send(), process.channel, process.connected,
101+
// process.disconnect().
102+
setupChildProcessIpcChannel();
103+
// If this is a worker in cluster mode, start up the communication
104+
// channel. This needs to be done before any user code gets executed
105+
// (including preload modules).
106+
initializeClusterIPC();
107+
108+
// TODO(joyeecheung): do this for worker threads as well.
109+
require('internal/v8/startup_snapshot').runDeserializeCallbacks();
110+
} else {
111+
assert(!internalBinding('worker').isMainThread);
112+
// The setup should be called in LOAD_SCRIPT message handler.
113+
assert(!initialzeModules);
114+
}
115+
116+
if (initialzeModules) {
117+
setupUserModules();
98118
}
119+
}
99120

121+
function setupUserModules() {
100122
initializeCJSLoader();
101123
initializeESMLoader();
102124
const CJSLoader = require('internal/modules/cjs/loader');
103125
assert(!CJSLoader.hasLoadedAnyUserCJSModule);
104126
loadPreloadModules();
127+
// Need to be done after --require setup.
105128
initializeFrozenIntrinsics();
106129
}
107130

@@ -476,7 +499,7 @@ function initializeClusterIPC() {
476499
}
477500
}
478501

479-
function initializePolicy() {
502+
function readPolicyFromDisk() {
480503
const experimentalPolicy = getOptionValue('--experimental-policy');
481504
if (experimentalPolicy) {
482505
process.emitWarning('Policies are experimental.',
@@ -520,8 +543,9 @@ function initializePolicy() {
520543
throw new ERR_MANIFEST_ASSERT_INTEGRITY(manifestURL, realIntegrities);
521544
}
522545
}
523-
require('internal/process/policy')
524-
.setup(src, manifestURL.href);
546+
return {
547+
manifestSrc: src, manifestURL: manifestURL.href
548+
};
525549
}
526550
}
527551

@@ -603,25 +627,8 @@ function markBootstrapComplete() {
603627
}
604628

605629
module.exports = {
606-
refreshRuntimeOptions,
607-
patchProcessObject,
608-
setupCoverageHooks,
609-
setupWarningHandler,
610-
setupFetch,
611-
setupWebCrypto,
612-
setupCustomEvent,
613-
setupDebugEnv,
614-
setupPerfHooks,
630+
setupUserModules,
615631
prepareMainThreadExecution,
616-
initializeDeprecations,
617-
initializeESMLoader,
618-
initializeFrozenIntrinsics,
619-
initializeSourceMapsHandlers,
620-
loadPreloadModules,
621-
setupTraceCategoryState,
622-
setupInspectorHooks,
623-
initializeReport,
624-
initializeCJSLoader,
625-
initializeWASI,
632+
prepareWorkerThreadExecution,
626633
markBootstrapComplete
627634
};

0 commit comments

Comments
 (0)
Please sign in to comment.