diff options
Diffstat (limited to 'runtime')
-rw-r--r-- | runtime/js/30_os.js | 11 | ||||
-rw-r--r-- | runtime/lib.rs | 11 | ||||
-rw-r--r-- | runtime/ops/os.rs | 10 |
3 files changed, 29 insertions, 3 deletions
diff --git a/runtime/js/30_os.js b/runtime/js/30_os.js index 15df6f554..f6bada6a5 100644 --- a/runtime/js/30_os.js +++ b/runtime/js/30_os.js @@ -31,7 +31,14 @@ exitHandler = fn; } - function exit(code = 0) { + function exit(code) { + // Set exit code first so unload event listeners can override it. + if (typeof code === "number") { + core.opSync("op_set_exit_code", code); + } else { + code = 0; + } + // Dispatches `unload` only when it's not dispatched yet. if (!window[SymbolFor("isUnloadDispatched")]) { // Invokes the `unload` hooks before exiting @@ -44,7 +51,7 @@ return; } - core.opSync("op_exit", code); + core.opSync("op_exit"); throw new Error("Code not reachable"); } diff --git a/runtime/lib.rs b/runtime/lib.rs index fb6159dd9..ca250ce20 100644 --- a/runtime/lib.rs +++ b/runtime/lib.rs @@ -1,5 +1,7 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +use std::sync::atomic::AtomicI32; + pub use deno_broadcast_channel; pub use deno_console; pub use deno_crypto; @@ -29,3 +31,12 @@ pub mod worker; mod worker_bootstrap; pub use worker_bootstrap::BootstrapOptions; + +// The global may not be very elegant but: +// +// 1. op_exit() calls std::process::exit() so there is not much point storing +// the exit code in runtime state +// +// 2. storing it in runtime state makes retrieving it again in cli/main.rs +// unduly complicated +pub static EXIT_CODE: AtomicI32 = AtomicI32::new(0); diff --git a/runtime/ops/os.rs b/runtime/ops/os.rs index 0a6269ac5..8e96de75d 100644 --- a/runtime/ops/os.rs +++ b/runtime/ops/os.rs @@ -10,6 +10,7 @@ use deno_core::OpState; use serde::Serialize; use std::collections::HashMap; use std::env; +use std::sync::atomic::Ordering::Relaxed; pub fn init() -> Extension { Extension::builder() @@ -23,6 +24,7 @@ pub fn init() -> Extension { ("op_hostname", op_sync(op_hostname)), ("op_loadavg", op_sync(op_loadavg)), ("op_os_release", op_sync(op_os_release)), + ("op_set_exit_code", op_sync(op_set_exit_code)), ("op_system_memory_info", op_sync(op_system_memory_info)), ]) .build() @@ -95,7 +97,13 @@ fn op_delete_env( Ok(()) } -fn op_exit(_state: &mut OpState, code: i32, _: ()) -> Result<(), AnyError> { +fn op_set_exit_code(_: &mut OpState, code: i32, _: ()) -> Result<(), AnyError> { + crate::EXIT_CODE.store(code, Relaxed); + Ok(()) +} + +fn op_exit(_: &mut OpState, _: (), _: ()) -> Result<(), AnyError> { + let code = crate::EXIT_CODE.load(Relaxed); std::process::exit(code) } |