mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
fix: use 'deno_signals' crate for signal handling (#30204)
Follow up to https://github.com/denoland/deno/pull/30029. Definition of signal numbers/names were moved from `ext/os` to `ext/signals`. All occurrences of `tokio::signal` API were replaced with helpers from `deno_signals` helpers. Additionally clippy lints were added to ensure `tokio::signal` is not used by accident. Closes https://github.com/denoland/deno/issues/30223 Co-authored-by: snek <the@snek.dev>
This commit is contained in:
parent
5a84806e9e
commit
22d1d98af3
14 changed files with 89 additions and 26 deletions
|
@ -7,6 +7,10 @@ use std::sync::atomic::AtomicU32;
|
|||
use std::sync::atomic::Ordering;
|
||||
|
||||
use signal_hook::consts::*;
|
||||
use tokio::sync::watch;
|
||||
|
||||
mod dict;
|
||||
pub use dict::*;
|
||||
|
||||
#[cfg(windows)]
|
||||
static SIGHUP: i32 = 1;
|
||||
|
@ -91,7 +95,14 @@ pub fn register(
|
|||
signal: i32,
|
||||
prevent_default: bool,
|
||||
f: Box<dyn Fn() + Send>,
|
||||
) -> u32 {
|
||||
) -> Result<u32, std::io::Error> {
|
||||
if is_forbidden(signal) {
|
||||
return Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
format!("Refusing to register signal {signal}"),
|
||||
));
|
||||
}
|
||||
|
||||
let (handle, handlers) = HANDLERS.get_or_init(|| {
|
||||
let handle = init();
|
||||
|
||||
|
@ -120,7 +131,7 @@ pub fn register(
|
|||
}
|
||||
}
|
||||
|
||||
id
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
pub fn unregister(signal: i32, id: u32) {
|
||||
|
@ -140,9 +151,9 @@ pub fn unregister(signal: i32, id: u32) {
|
|||
static BEFORE_EXIT: OnceLock<Mutex<Vec<Handler>>> = OnceLock::new();
|
||||
|
||||
pub fn before_exit(f: fn()) {
|
||||
register(SIGHUP, false, Box::new(f));
|
||||
register(SIGTERM, false, Box::new(f));
|
||||
register(SIGINT, false, Box::new(f));
|
||||
register(SIGHUP, false, Box::new(f)).unwrap();
|
||||
register(SIGTERM, false, Box::new(f)).unwrap();
|
||||
register(SIGINT, false, Box::new(f)).unwrap();
|
||||
BEFORE_EXIT
|
||||
.get_or_init(|| Mutex::new(vec![]))
|
||||
.lock()
|
||||
|
@ -162,3 +173,33 @@ pub fn run_exit() {
|
|||
pub fn is_forbidden(signo: i32) -> bool {
|
||||
FORBIDDEN.contains(&signo)
|
||||
}
|
||||
|
||||
pub struct SignalStream {
|
||||
rx: watch::Receiver<()>,
|
||||
}
|
||||
|
||||
impl SignalStream {
|
||||
pub async fn recv(&mut self) -> Option<()> {
|
||||
self.rx.changed().await.ok()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn signal_stream(signo: i32) -> Result<SignalStream, std::io::Error> {
|
||||
let (tx, rx) = watch::channel(());
|
||||
let cb = Box::new(move || {
|
||||
tx.send_replace(());
|
||||
});
|
||||
register(signo, true, cb)?;
|
||||
Ok(SignalStream { rx })
|
||||
}
|
||||
|
||||
pub async fn ctrl_c() -> std::io::Result<()> {
|
||||
let mut stream = signal_stream(libc::SIGINT)?;
|
||||
match stream.recv().await {
|
||||
Some(_) => Ok(()),
|
||||
None => Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"failed to receive SIGINT signal",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue