Skip to content

Commit d1809c0

Browse files
joyeecheungruyadorno
authored andcommittedDec 20, 2024
sea: only assert snapshot main function for main threads
Snapshot main functions are only loaded for main threads in single executable applications. Update the check to avoid asserting it in worker threads - this allows worker threads to be spawned in snapshot main functions bundled into a single executable application. PR-URL: #56120 Fixes: #56077 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 6630ccc commit d1809c0

File tree

2 files changed

+85
-1
lines changed

2 files changed

+85
-1
lines changed
 

‎src/node.cc

+5-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
369369
CHECK(!env->isolate_data()->is_building_snapshot());
370370

371371
#ifndef DISABLE_SINGLE_EXECUTABLE_APPLICATION
372-
if (sea::IsSingleExecutable()) {
372+
// Snapshot in SEA is only loaded for the main thread.
373+
if (sea::IsSingleExecutable() && env->is_main_thread()) {
373374
sea::SeaResource sea = sea::FindSingleExecutableResource();
374375
// The SEA preparation blob building process should already enforce this,
375376
// this check is just here to guard against the unlikely case where
@@ -391,6 +392,9 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
391392
// move the pre-execution part into a different file that can be
392393
// reused when dealing with user-defined main functions.
393394
if (!env->snapshot_deserialize_main().IsEmpty()) {
395+
// Custom worker snapshot is not supported yet,
396+
// so workers can't have deserialize main functions.
397+
CHECK(env->is_main_thread());
394398
return env->RunSnapshotDeserializeMain();
395399
}
396400

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
'use strict';
2+
3+
require('../common');
4+
5+
const {
6+
generateSEA,
7+
skipIfSingleExecutableIsNotSupported,
8+
} = require('../common/sea');
9+
10+
skipIfSingleExecutableIsNotSupported();
11+
12+
// This tests the snapshot support in single executable applications.
13+
14+
const tmpdir = require('../common/tmpdir');
15+
const { writeFileSync, existsSync } = require('fs');
16+
const {
17+
spawnSyncAndAssert, spawnSyncAndExitWithoutError,
18+
} = require('../common/child_process');
19+
const assert = require('assert');
20+
21+
const configFile = tmpdir.resolve('sea-config.json');
22+
const seaPrepBlob = tmpdir.resolve('sea-prep.blob');
23+
const outputFile = tmpdir.resolve(process.platform === 'win32' ? 'sea.exe' : 'sea');
24+
25+
{
26+
tmpdir.refresh();
27+
28+
// FIXME(joyeecheung): currently `worker_threads` cannot be loaded during the
29+
// snapshot building process because internal/worker.js is accessing isMainThread at
30+
// the top level (and there are maybe more code that access these at the top-level),
31+
// and have to be loaded in the deserialized snapshot main function.
32+
// Change these states to be accessed on-demand.
33+
const code = `
34+
const {
35+
setDeserializeMainFunction,
36+
} = require('v8').startupSnapshot;
37+
setDeserializeMainFunction(() => {
38+
const { Worker } = require('worker_threads');
39+
new Worker("console.log('Hello from Worker')", { eval: true });
40+
});
41+
`;
42+
43+
writeFileSync(tmpdir.resolve('snapshot.js'), code, 'utf-8');
44+
writeFileSync(configFile, `
45+
{
46+
"main": "snapshot.js",
47+
"output": "sea-prep.blob",
48+
"useSnapshot": true
49+
}
50+
`);
51+
52+
spawnSyncAndExitWithoutError(
53+
process.execPath,
54+
['--experimental-sea-config', 'sea-config.json'],
55+
{
56+
cwd: tmpdir.path,
57+
env: {
58+
NODE_DEBUG_NATIVE: 'SEA',
59+
...process.env,
60+
},
61+
});
62+
63+
assert(existsSync(seaPrepBlob));
64+
65+
generateSEA(outputFile, process.execPath, seaPrepBlob);
66+
67+
spawnSyncAndAssert(
68+
outputFile,
69+
{
70+
env: {
71+
NODE_DEBUG_NATIVE: 'SEA',
72+
...process.env,
73+
}
74+
},
75+
{
76+
trim: true,
77+
stdout: 'Hello from Worker'
78+
}
79+
);
80+
}

0 commit comments

Comments
 (0)