1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

refactor: setup child process pipe in Rust (#21579)

Avoid passing the fd into JS and back into Rust. Instead we setup the
child's end of the pipe directly using a special Rust op.
This commit is contained in:
Divy Srivastava 2023-12-15 16:20:05 +05:30 committed by GitHub
parent 62e3f5060e
commit 81a6504e67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 41 additions and 9 deletions

View file

@ -30,6 +30,7 @@ mod path;
mod polyfill; mod polyfill;
mod resolution; mod resolution;
pub use ops::ipc::ChildPipeFd;
pub use ops::v8::VM_CONTEXT_INDEX; pub use ops::v8::VM_CONTEXT_INDEX;
pub use package_json::PackageJson; pub use package_json::PackageJson;
pub use path::PathClean; pub use path::PathClean;
@ -313,6 +314,7 @@ deno_core::extension!(deno_node,
ops::util::op_node_guess_handle_type, ops::util::op_node_guess_handle_type,
ops::crypto::op_node_create_private_key, ops::crypto::op_node_create_private_key,
ops::ipc::op_node_ipc_pipe, ops::ipc::op_node_ipc_pipe,
ops::ipc::op_node_child_ipc_pipe,
ops::ipc::op_node_ipc_write, ops::ipc::op_node_ipc_write,
ops::ipc::op_node_ipc_read, ops::ipc::op_node_ipc_read,
], ],

View file

@ -6,6 +6,8 @@ pub use unix::*;
#[cfg(windows)] #[cfg(windows)]
pub use windows::*; pub use windows::*;
pub struct ChildPipeFd(pub i32);
#[cfg(unix)] #[cfg(unix)]
mod unix { mod unix {
use std::cell::RefCell; use std::cell::RefCell;
@ -46,6 +48,22 @@ mod unix {
Ok(state.resource_table.add(IpcJsonStreamResource::new(fd)?)) Ok(state.resource_table.add(IpcJsonStreamResource::new(fd)?))
} }
// Open IPC pipe from bootstrap options.
#[op2]
#[smi]
pub fn op_node_child_ipc_pipe(
state: &mut OpState,
) -> Result<Option<ResourceId>, AnyError> {
let fd = match state.try_borrow_mut::<crate::ChildPipeFd>() {
Some(child_pipe_fd) => child_pipe_fd.0,
None => return Ok(None),
};
Ok(Some(
state.resource_table.add(IpcJsonStreamResource::new(fd)?),
))
}
#[op2(async)] #[op2(async)]
pub async fn op_node_ipc_write( pub async fn op_node_ipc_write(
state: Rc<RefCell<OpState>>, state: Rc<RefCell<OpState>>,
@ -492,6 +510,12 @@ mod windows {
Err(deno_core::error::not_supported()) Err(deno_core::error::not_supported())
} }
#[op2(fast)]
#[smi]
pub fn op_node_child_ipc_pipe() -> Result<i32, AnyError> {
Ok(-1)
}
#[op2(async)] #[op2(async)]
pub async fn op_node_ipc_write() -> Result<(), AnyError> { pub async fn op_node_ipc_write() -> Result<(), AnyError> {
Err(deno_core::error::not_supported()) Err(deno_core::error::not_supported())

View file

@ -12,7 +12,6 @@ let initialized = false;
function initialize( function initialize(
usesLocalNodeModulesDir, usesLocalNodeModulesDir,
argv0, argv0,
ipcFd,
) { ) {
if (initialized) { if (initialized) {
throw Error("Node runtime already initialized"); throw Error("Node runtime already initialized");
@ -38,7 +37,7 @@ function initialize(
// but it's the only way to get `args` and `version` and this point. // but it's the only way to get `args` and `version` and this point.
internals.__bootstrapNodeProcess(argv0, Deno.args, Deno.version); internals.__bootstrapNodeProcess(argv0, Deno.args, Deno.version);
internals.__initWorkerThreads(); internals.__initWorkerThreads();
internals.__setupChildProcessIpcChannel(ipcFd); internals.__setupChildProcessIpcChannel();
// `Deno[Deno.internal].requireImpl` will be unreachable after this line. // `Deno[Deno.internal].requireImpl` will be unreachable after this line.
delete internals.requireImpl; delete internals.requireImpl;
} }

View file

@ -49,6 +49,7 @@ import {
} from "ext:deno_node/internal/util.mjs"; } from "ext:deno_node/internal/util.mjs";
const { core } = globalThis.__bootstrap; const { core } = globalThis.__bootstrap;
const ops = core.ops;
const MAX_BUFFER = 1024 * 1024; const MAX_BUFFER = 1024 * 1024;
@ -822,7 +823,8 @@ export function execFileSync(
return ret.stdout as string | Buffer; return ret.stdout as string | Buffer;
} }
function setupChildProcessIpcChannel(fd: number) { function setupChildProcessIpcChannel() {
const fd = ops.op_node_child_ipc_pipe();
if (typeof fd != "number" || fd < 0) return; if (typeof fd != "number" || fd < 0) return;
setupChannel(process, fd); setupChannel(process, fd);
} }

View file

@ -440,7 +440,6 @@ function bootstrapMainRuntime(runtimeOptions) {
3: inspectFlag, 3: inspectFlag,
5: hasNodeModulesDir, 5: hasNodeModulesDir,
6: maybeBinaryNpmCommandName, 6: maybeBinaryNpmCommandName,
7: nodeIpcFd,
} = runtimeOptions; } = runtimeOptions;
performance.setTimeOrigin(DateNow()); performance.setTimeOrigin(DateNow());
@ -546,7 +545,7 @@ function bootstrapMainRuntime(runtimeOptions) {
ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs)); ObjectDefineProperty(globalThis, "Deno", util.readOnly(finalDenoNs));
if (nodeBootstrap) { if (nodeBootstrap) {
nodeBootstrap(hasNodeModulesDir, maybeBinaryNpmCommandName, nodeIpcFd); nodeBootstrap(hasNodeModulesDir, maybeBinaryNpmCommandName);
} }
} }

View file

@ -487,7 +487,16 @@ impl MainWorker {
} }
pub fn bootstrap(&mut self, options: BootstrapOptions) { pub fn bootstrap(&mut self, options: BootstrapOptions) {
self.js_runtime.op_state().borrow_mut().put(options.clone()); // Setup bootstrap options for ops.
{
let op_state = self.js_runtime.op_state();
let mut state = op_state.borrow_mut();
state.put(options.clone());
if let Some(node_ipc_fd) = options.node_ipc_fd {
state.put(deno_node::ChildPipeFd(node_ipc_fd));
}
}
let scope = &mut self.js_runtime.handle_scope(); let scope = &mut self.js_runtime.handle_scope();
let args = options.as_v8(scope); let args = options.as_v8(scope);
let bootstrap_fn = self.bootstrap_fn_global.take().unwrap(); let bootstrap_fn = self.bootstrap_fn_global.take().unwrap();

View file

@ -117,8 +117,6 @@ struct BootstrapV8<'a>(
bool, bool,
// maybe_binary_npm_command_name // maybe_binary_npm_command_name
Option<&'a str>, Option<&'a str>,
// node_ipc_fd
i32,
); );
impl BootstrapOptions { impl BootstrapOptions {
@ -138,7 +136,6 @@ impl BootstrapOptions {
self.enable_testing_features, self.enable_testing_features,
self.has_node_modules_dir, self.has_node_modules_dir,
self.maybe_binary_npm_command_name.as_deref(), self.maybe_binary_npm_command_name.as_deref(),
self.node_ipc_fd.unwrap_or(-1),
); );
bootstrap.serialize(ser).unwrap() bootstrap.serialize(ser).unwrap()