Skip to content

Commit fa28439

Browse files
joyeecheungjuanarbol
authored andcommitted
bootstrap: make I/O streams work with user-land snapshot
Use the mksnapshot cleanup hooks to release the references to the native streams so that they can be destroyed right before the snapshot is taken, and move the initialization of the global console to pre-execution so that they can be re-initialized during snapshot dehydration. This makes it possible for user-land snapshots to use the I/O during snapshot building. PR-URL: #42466 Reviewed-By: Darshan Sen <[email protected]> Reviewed-By: Mohammed Keyvanzadeh <[email protected]> Reviewed-By: Khaidi Chu <[email protected]> Reviewed-By: Chengzhong Wu <[email protected]>
1 parent 6b14bd8 commit fa28439

File tree

4 files changed

+45
-8
lines changed

4 files changed

+45
-8
lines changed

lib/internal/bootstrap/pre_execution.js

+6
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ function patchProcessObject(expandArgv1) {
121121
}
122122
}
123123

124+
// We need to initialize the global console here again with process.stdout
125+
// and friends for snapshot deserialization.
126+
const globalConsole = require('internal/console/global');
127+
const { initializeGlobalConsole } = require('internal/console/constructor');
128+
initializeGlobalConsole(globalConsole);
129+
124130
// TODO(joyeecheung): most of these should be deprecated and removed,
125131
// except some that we need to be able to mutate during run time.
126132
addReadOnlyProcessAlias('_eval', '--eval');

lib/internal/bootstrap/switches/is_main_thread.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -122,27 +122,53 @@ let stdin;
122122
let stdout;
123123
let stderr;
124124

125+
let stdoutDestroy;
126+
let stderrDestroy;
127+
128+
function refreshStdoutOnSigWinch() {
129+
stdout._refreshSize();
130+
}
131+
132+
function refreshStderrOnSigWinch() {
133+
stderr._refreshSize();
134+
}
135+
125136
function getStdout() {
126137
if (stdout) return stdout;
127138
stdout = createWritableStdioStream(1);
128139
stdout.destroySoon = stdout.destroy;
129140
// Override _destroy so that the fd is never actually closed.
141+
stdoutDestroy = stdout._destroy;
130142
stdout._destroy = dummyDestroy;
131143
if (stdout.isTTY) {
132-
process.on('SIGWINCH', () => stdout._refreshSize());
144+
process.on('SIGWINCH', refreshStdoutOnSigWinch);
133145
}
146+
147+
internalBinding('mksnapshot').cleanups.push(function cleanupStdout() {
148+
stdout._destroy = stdoutDestroy;
149+
stdout.destroy();
150+
process.removeListener('SIGWINCH', refreshStdoutOnSigWinch);
151+
stdout = undefined;
152+
});
134153
return stdout;
135154
}
136155

137156
function getStderr() {
138157
if (stderr) return stderr;
139158
stderr = createWritableStdioStream(2);
140159
stderr.destroySoon = stderr.destroy;
160+
stderrDestroy = stderr._destroy;
141161
// Override _destroy so that the fd is never actually closed.
142162
stderr._destroy = dummyDestroy;
143163
if (stderr.isTTY) {
144-
process.on('SIGWINCH', () => stderr._refreshSize());
164+
process.on('SIGWINCH', refreshStderrOnSigWinch);
145165
}
166+
internalBinding('mksnapshot').cleanups.push(function cleanupStderr() {
167+
stderr._destroy = stderrDestroy;
168+
stderr.destroy();
169+
process.removeListener('SIGWINCH', refreshStderrOnSigWinch);
170+
stderr = undefined;
171+
});
146172
return stderr;
147173
}
148174

@@ -229,6 +255,10 @@ function getStdin() {
229255
}
230256
}
231257

258+
internalBinding('mksnapshot').cleanups.push(function cleanupStdin() {
259+
stdin.destroy();
260+
stdin = undefined;
261+
});
232262
return stdin;
233263
}
234264

lib/internal/console/constructor.js

+6
Original file line numberDiff line numberDiff line change
@@ -669,9 +669,15 @@ Console.prototype.dirxml = Console.prototype.log;
669669
Console.prototype.error = Console.prototype.warn;
670670
Console.prototype.groupCollapsed = Console.prototype.group;
671671

672+
function initializeGlobalConsole(globalConsole) {
673+
globalConsole[kBindStreamsLazy](process);
674+
globalConsole[kBindProperties](true, 'auto');
675+
}
676+
672677
module.exports = {
673678
Console,
674679
kBindStreamsLazy,
675680
kBindProperties,
681+
initializeGlobalConsole,
676682
formatTime // exported for tests
677683
};

lib/internal/console/global.js

+1-6
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,7 @@ const {
2121
} = primordials;
2222

2323
const {
24-
Console,
25-
kBindStreamsLazy,
26-
kBindProperties
24+
Console
2725
} = require('internal/console/constructor');
2826

2927
const globalConsole = ObjectCreate({});
@@ -44,9 +42,6 @@ for (const prop of ReflectOwnKeys(Console.prototype)) {
4442
ReflectDefineProperty(globalConsole, prop, desc);
4543
}
4644

47-
globalConsole[kBindStreamsLazy](process);
48-
globalConsole[kBindProperties](true, 'auto');
49-
5045
// This is a legacy feature - the Console constructor is exposed on
5146
// the global console instance.
5247
globalConsole.Console = Console;

0 commit comments

Comments
 (0)