Skip to content

Commit c45b6ae

Browse files
joyeecheungRafaelGSS
authored andcommitted
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 <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 824dcfc commit c45b6ae

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,29 +44,14 @@ 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
const { exitCodes: { kGenericUserError } } = internalBinding('errors');
7053

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

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

@@ -127,23 +96,11 @@ port.on('message', (message) => {
12796
hasStdin
12897
} = message;
12998

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

@@ -165,10 +122,10 @@ port.on('message', (message) => {
165122
};
166123
workerIo.sharedCwdCounter = cwdCounter;
167124

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

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

lib/internal/process/pre_execution.js

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

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

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

4559
// Patch the process object with legacy properties and normalizations
@@ -61,48 +75,57 @@ function prepareMainThreadExecution(expandArgv1 = false,
6175
}
6276

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

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

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

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

@@ -482,7 +505,7 @@ function initializeClusterIPC() {
482505
}
483506
}
484507

485-
function initializePolicy() {
508+
function readPolicyFromDisk() {
486509
const experimentalPolicy = getOptionValue('--experimental-policy');
487510
if (experimentalPolicy) {
488511
process.emitWarning('Policies are experimental.',
@@ -526,8 +549,9 @@ function initializePolicy() {
526549
throw new ERR_MANIFEST_ASSERT_INTEGRITY(manifestURL, realIntegrities);
527550
}
528551
}
529-
require('internal/process/policy')
530-
.setup(src, manifestURL.href);
552+
return {
553+
manifestSrc: src, manifestURL: manifestURL.href
554+
};
531555
}
532556
}
533557

@@ -609,25 +633,8 @@ function markBootstrapComplete() {
609633
}
610634

611635
module.exports = {
612-
refreshRuntimeOptions,
613-
patchProcessObject,
614-
setupCoverageHooks,
615-
setupWarningHandler,
616-
setupFetch,
617-
setupWebCrypto,
618-
setupCustomEvent,
619-
setupDebugEnv,
620-
setupPerfHooks,
636+
setupUserModules,
621637
prepareMainThreadExecution,
622-
initializeDeprecations,
623-
initializeESMLoader,
624-
initializeFrozenIntrinsics,
625-
initializeSourceMapsHandlers,
626-
loadPreloadModules,
627-
setupTraceCategoryState,
628-
setupInspectorHooks,
629-
initializeReport,
630-
initializeCJSLoader,
631-
initializeWASI,
638+
prepareWorkerThreadExecution,
632639
markBootstrapComplete
633640
};

0 commit comments

Comments
 (0)