diff --git a/Cargo.lock b/Cargo.lock index e2006c7..1a874b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,6 @@ dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "notify 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "signal 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -212,21 +211,6 @@ name = "semver" version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "signal" -version = "0.3.2" -source = "git+https://github.com/mattgreen/signal#c4cd101018aa4c1647a973c8c94fc5b3613e644d" -dependencies = [ - "libc 0.2.16 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "signal" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -replace = "signal 0.3.2 (git+https://github.com/mattgreen/signal)" - [[package]] name = "slab" version = "0.1.3" @@ -324,8 +308,6 @@ dependencies = [ "checksum notify 2.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4e0e7eec936337952c4228b023007528a33b2fa039d96c2e8f32d764221a9c07" "checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" "checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" -"checksum signal 0.3.2 (git+https://github.com/mattgreen/signal)" = "" -"checksum signal 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "904a4bba60e8e7a53b7a7eec8f59084a9ceafe3df5aa9d24846a83a5e351aa34" "checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e" "checksum term_size 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3f7f5f3f71b0040cecc71af239414c23fd3c73570f5ff54cf50e03cef637f2a0" "checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af" diff --git a/Cargo.toml b/Cargo.toml index 27e276b..15765d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,11 +32,7 @@ features = [] [target.'cfg(unix)'.dependencies] nix = "0.6.0" -signal = "0.3.2" [target.'cfg(windows)'.dependencies] winapi = "0.2.8" kernel32-sys = "0.2.2" - -[replace] -"signal:0.3.2" = { git = 'https://github.com/mattgreen/signal' } diff --git a/src/interrupt_handler.rs b/src/interrupt_handler.rs index 0ea188d..6b38b55 100644 --- a/src/interrupt_handler.rs +++ b/src/interrupt_handler.rs @@ -1,23 +1,29 @@ use std::sync::Mutex; +use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::{channel, Receiver, Sender, SendError}; lazy_static! { static ref INTERRUPT_TX: Mutex>> = Mutex::new(None); + static ref INTERRUPT_REQUESTED: AtomicBool = AtomicBool::new(false); } -/// On Unix platforms, spawn a thread and use the signal crate -/// to relay signals back to the main thread. -#[cfg(unix)] +/// On Unix platforms, mask reception of SIGINT/SIGTERM, spawn a thread, +/// and sigwait on those signals to safely relay them. pub fn install() -> Receiver<()> { use std::thread; - use nix::sys::signal::{SIGTERM, SIGINT}; - use signal::trap::Trap; + use nix::sys::signal::{SigSet, SIGTERM, SIGINT}; + + let mut mask = SigSet::empty(); + mask.add(SIGTERM).expect("unable to add SIGTERM to mask"); + mask.add(SIGINT).expect("unable to add SIGINT to mask"); + mask.thread_set_mask().expect("unable to set signal mask"); - let trap = Trap::trap(&[SIGTERM, SIGINT]); let rx = create_channel(); thread::spawn(move || { - for _ in trap { + loop { + let _ = mask.wait().expect("unable to sigwait"); + let result = send_interrupt(); if result.is_err() { break; @@ -48,6 +54,10 @@ pub fn install() -> Receiver<()> { rx } +pub fn interrupt_requested() -> bool { + INTERRUPT_REQUESTED.load(Ordering::Relaxed) +} + fn create_channel() -> Receiver<()> { let mut guard = INTERRUPT_TX.lock().unwrap(); if (*guard).is_some() { @@ -61,6 +71,8 @@ fn create_channel() -> Receiver<()> { } fn send_interrupt() -> Result<(), SendError<()>> { + INTERRUPT_REQUESTED.store(true, Ordering::Relaxed); + if let Some(ref mut tx) = *INTERRUPT_TX.lock().unwrap() { tx.send(()) } else {