mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
refactor: ensure exit code reference is passed to all workers (#14814)
This commit is contained in:
parent
4911acb148
commit
ba13b8e2a9
5 changed files with 31 additions and 30 deletions
|
@ -179,7 +179,7 @@ fn create_web_worker_callback(
|
||||||
broadcast_channel: ps.broadcast_channel.clone(),
|
broadcast_channel: ps.broadcast_channel.clone(),
|
||||||
shared_array_buffer_store: Some(ps.shared_array_buffer_store.clone()),
|
shared_array_buffer_store: Some(ps.shared_array_buffer_store.clone()),
|
||||||
compiled_wasm_module_store: Some(ps.compiled_wasm_module_store.clone()),
|
compiled_wasm_module_store: Some(ps.compiled_wasm_module_store.clone()),
|
||||||
maybe_exit_code: args.maybe_exit_code,
|
exit_code: args.exit_code,
|
||||||
stdio: stdio.clone(),
|
stdio: stdio.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use super::utils::into_string;
|
use super::utils::into_string;
|
||||||
use crate::permissions::Permissions;
|
use crate::permissions::Permissions;
|
||||||
|
use crate::worker::ExitCode;
|
||||||
use deno_core::error::{type_error, AnyError};
|
use deno_core::error::{type_error, AnyError};
|
||||||
use deno_core::op;
|
use deno_core::op;
|
||||||
use deno_core::url::Url;
|
use deno_core::url::Url;
|
||||||
|
@ -10,11 +11,8 @@ use deno_core::OpState;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::sync::atomic::AtomicI32;
|
|
||||||
use std::sync::atomic::Ordering::Relaxed;
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub fn init(maybe_exit_code: Option<Arc<AtomicI32>>) -> Extension {
|
pub fn init(exit_code: ExitCode) -> Extension {
|
||||||
Extension::builder()
|
Extension::builder()
|
||||||
.ops(vec![
|
.ops(vec![
|
||||||
op_env::decl(),
|
op_env::decl(),
|
||||||
|
@ -33,8 +31,7 @@ pub fn init(maybe_exit_code: Option<Arc<AtomicI32>>) -> Extension {
|
||||||
op_system_memory_info::decl(),
|
op_system_memory_info::decl(),
|
||||||
])
|
])
|
||||||
.state(move |state| {
|
.state(move |state| {
|
||||||
let exit_code = maybe_exit_code.clone().unwrap_or_default();
|
state.put::<ExitCode>(exit_code.clone());
|
||||||
state.put::<Arc<AtomicI32>>(exit_code);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.build()
|
.build()
|
||||||
|
@ -105,12 +102,12 @@ fn op_delete_env(state: &mut OpState, key: String) -> Result<(), AnyError> {
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
fn op_set_exit_code(state: &mut OpState, code: i32) {
|
fn op_set_exit_code(state: &mut OpState, code: i32) {
|
||||||
state.borrow_mut::<Arc<AtomicI32>>().store(code, Relaxed);
|
state.borrow_mut::<ExitCode>().set(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
fn op_exit(state: &mut OpState) {
|
fn op_exit(state: &mut OpState) {
|
||||||
let code = state.borrow::<Arc<AtomicI32>>().load(Relaxed);
|
let code = state.borrow::<ExitCode>().get();
|
||||||
std::process::exit(code)
|
std::process::exit(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ use crate::web_worker::WebWorkerHandle;
|
||||||
use crate::web_worker::WebWorkerType;
|
use crate::web_worker::WebWorkerType;
|
||||||
use crate::web_worker::WorkerControlEvent;
|
use crate::web_worker::WorkerControlEvent;
|
||||||
use crate::web_worker::WorkerId;
|
use crate::web_worker::WorkerId;
|
||||||
|
use crate::worker::ExitCode;
|
||||||
use crate::worker::FormatJsErrorFn;
|
use crate::worker::FormatJsErrorFn;
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::futures::future::LocalFutureObj;
|
use deno_core::futures::future::LocalFutureObj;
|
||||||
|
@ -27,7 +28,6 @@ use log::debug;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::AtomicI32;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
pub struct CreateWebWorkerArgs {
|
pub struct CreateWebWorkerArgs {
|
||||||
|
@ -37,7 +37,7 @@ pub struct CreateWebWorkerArgs {
|
||||||
pub permissions: Permissions,
|
pub permissions: Permissions,
|
||||||
pub main_module: ModuleSpecifier,
|
pub main_module: ModuleSpecifier,
|
||||||
pub worker_type: WebWorkerType,
|
pub worker_type: WebWorkerType,
|
||||||
pub maybe_exit_code: Option<Arc<AtomicI32>>,
|
pub exit_code: ExitCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CreateWebWorkerCb = dyn Fn(CreateWebWorkerArgs) -> (WebWorker, SendableWebWorkerHandle)
|
pub type CreateWebWorkerCb = dyn Fn(CreateWebWorkerArgs) -> (WebWorker, SendableWebWorkerHandle)
|
||||||
|
@ -171,11 +171,7 @@ fn op_create_worker(
|
||||||
parent_permissions.clone()
|
parent_permissions.clone()
|
||||||
};
|
};
|
||||||
let parent_permissions = parent_permissions.clone();
|
let parent_permissions = parent_permissions.clone();
|
||||||
// `try_borrow` here, because worker might have been started without
|
let exit_code = state.borrow::<ExitCode>().clone();
|
||||||
// access to `Deno` namespace.
|
|
||||||
// TODO(bartlomieju): can a situation happen when parent doesn't
|
|
||||||
// have access to `exit_code` but the child does?
|
|
||||||
let maybe_exit_code = state.try_borrow::<Arc<AtomicI32>>().cloned();
|
|
||||||
let worker_id = state.take::<WorkerId>();
|
let worker_id = state.take::<WorkerId>();
|
||||||
let create_web_worker_cb = state.take::<CreateWebWorkerCbHolder>();
|
let create_web_worker_cb = state.take::<CreateWebWorkerCbHolder>();
|
||||||
state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb.clone());
|
state.put::<CreateWebWorkerCbHolder>(create_web_worker_cb.clone());
|
||||||
|
@ -211,7 +207,7 @@ fn op_create_worker(
|
||||||
permissions: worker_permissions,
|
permissions: worker_permissions,
|
||||||
main_module: module_specifier.clone(),
|
main_module: module_specifier.clone(),
|
||||||
worker_type,
|
worker_type,
|
||||||
maybe_exit_code,
|
exit_code,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send thread safe handle from newly created worker to host thread
|
// Send thread safe handle from newly created worker to host thread
|
||||||
|
|
|
@ -6,6 +6,7 @@ use crate::ops;
|
||||||
use crate::ops::io::Stdio;
|
use crate::ops::io::Stdio;
|
||||||
use crate::permissions::Permissions;
|
use crate::permissions::Permissions;
|
||||||
use crate::tokio_util::run_basic;
|
use crate::tokio_util::run_basic;
|
||||||
|
use crate::worker::ExitCode;
|
||||||
use crate::worker::FormatJsErrorFn;
|
use crate::worker::FormatJsErrorFn;
|
||||||
use crate::BootstrapOptions;
|
use crate::BootstrapOptions;
|
||||||
use deno_broadcast_channel::InMemoryBroadcastChannel;
|
use deno_broadcast_channel::InMemoryBroadcastChannel;
|
||||||
|
@ -40,7 +41,6 @@ use std::cell::RefCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::atomic::AtomicI32;
|
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::task::Context;
|
use std::task::Context;
|
||||||
|
@ -335,7 +335,7 @@ pub struct WebWorkerOptions {
|
||||||
pub broadcast_channel: InMemoryBroadcastChannel,
|
pub broadcast_channel: InMemoryBroadcastChannel,
|
||||||
pub shared_array_buffer_store: Option<SharedArrayBufferStore>,
|
pub shared_array_buffer_store: Option<SharedArrayBufferStore>,
|
||||||
pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>,
|
pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>,
|
||||||
pub maybe_exit_code: Option<Arc<AtomicI32>>,
|
pub exit_code: ExitCode,
|
||||||
pub stdio: Stdio,
|
pub stdio: Stdio,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,11 +421,7 @@ impl WebWorker {
|
||||||
unstable,
|
unstable,
|
||||||
options.unsafely_ignore_certificate_errors.clone(),
|
options.unsafely_ignore_certificate_errors.clone(),
|
||||||
),
|
),
|
||||||
ops::os::init(Some(
|
ops::os::init(options.exit_code),
|
||||||
options
|
|
||||||
.maybe_exit_code
|
|
||||||
.expect("Worker has access to OS ops but exit code was not passed."),
|
|
||||||
)),
|
|
||||||
ops::permissions::init(),
|
ops::permissions::init(),
|
||||||
ops::process::init(),
|
ops::process::init(),
|
||||||
ops::spawn::init(),
|
ops::spawn::init(),
|
||||||
|
|
|
@ -35,6 +35,18 @@ use std::task::Poll;
|
||||||
|
|
||||||
pub type FormatJsErrorFn = dyn Fn(&JsError) -> String + Sync + Send;
|
pub type FormatJsErrorFn = dyn Fn(&JsError) -> String + Sync + Send;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ExitCode(Arc<AtomicI32>);
|
||||||
|
|
||||||
|
impl ExitCode {
|
||||||
|
pub fn get(&self) -> i32 {
|
||||||
|
self.0.load(Relaxed)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, code: i32) {
|
||||||
|
self.0.store(code, Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
/// This worker is created and used by almost all
|
/// This worker is created and used by almost all
|
||||||
/// subcommands in Deno executable.
|
/// subcommands in Deno executable.
|
||||||
///
|
///
|
||||||
|
@ -45,6 +57,7 @@ pub type FormatJsErrorFn = dyn Fn(&JsError) -> String + Sync + Send;
|
||||||
pub struct MainWorker {
|
pub struct MainWorker {
|
||||||
pub js_runtime: JsRuntime,
|
pub js_runtime: JsRuntime,
|
||||||
should_break_on_first_statement: bool,
|
should_break_on_first_statement: bool,
|
||||||
|
exit_code: ExitCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WorkerOptions {
|
pub struct WorkerOptions {
|
||||||
|
@ -98,6 +111,7 @@ impl MainWorker {
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
let exit_code = ExitCode(Arc::new(AtomicI32::new(0)));
|
||||||
|
|
||||||
// Internal modules
|
// Internal modules
|
||||||
let mut extensions: Vec<Extension> = vec![
|
let mut extensions: Vec<Extension> = vec![
|
||||||
|
@ -147,7 +161,7 @@ impl MainWorker {
|
||||||
unstable,
|
unstable,
|
||||||
options.unsafely_ignore_certificate_errors.clone(),
|
options.unsafely_ignore_certificate_errors.clone(),
|
||||||
),
|
),
|
||||||
ops::os::init(None),
|
ops::os::init(exit_code.clone()),
|
||||||
ops::permissions::init(),
|
ops::permissions::init(),
|
||||||
ops::process::init(),
|
ops::process::init(),
|
||||||
ops::signal::init(),
|
ops::signal::init(),
|
||||||
|
@ -181,6 +195,7 @@ impl MainWorker {
|
||||||
Self {
|
Self {
|
||||||
js_runtime,
|
js_runtime,
|
||||||
should_break_on_first_statement: options.should_break_on_first_statement,
|
should_break_on_first_statement: options.should_break_on_first_statement,
|
||||||
|
exit_code,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,11 +329,8 @@ impl MainWorker {
|
||||||
|
|
||||||
/// Return exit code set by the executed code (either in main worker
|
/// Return exit code set by the executed code (either in main worker
|
||||||
/// or one of child web workers).
|
/// or one of child web workers).
|
||||||
pub fn get_exit_code(&mut self) -> i32 {
|
pub fn get_exit_code(&self) -> i32 {
|
||||||
let op_state_rc = self.js_runtime.op_state();
|
self.exit_code.get()
|
||||||
let op_state = op_state_rc.borrow();
|
|
||||||
let exit_code = op_state.borrow::<Arc<AtomicI32>>().load(Relaxed);
|
|
||||||
exit_code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dispatches "load" event to the JavaScript runtime.
|
/// Dispatches "load" event to the JavaScript runtime.
|
||||||
|
|
Loading…
Add table
Reference in a new issue