diff --git a/ntex-server/CHANGES.md b/ntex-server/CHANGES.md index 39c7e457..df8b14ac 100644 --- a/ntex-server/CHANGES.md +++ b/ntex-server/CHANGES.md @@ -1,8 +1,12 @@ # Changes +## [1.0.4] - 2024-03-30 + +* Fix signals support #324 + ## [1.0.3] - 2024-03-29 -* Fix windows signals support +* Fix windows signals support #322 ## [1.0.2] - 2024-03-25 diff --git a/ntex-server/Cargo.toml b/ntex-server/Cargo.toml index 0918aa83..4af4af0b 100644 --- a/ntex-server/Cargo.toml +++ b/ntex-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ntex-server" -version = "1.0.3" +version = "1.0.4" authors = ["ntex contributors "] description = "Server for ntex framework" keywords = ["network", "framework", "async", "futures"] diff --git a/ntex-server/src/signals.rs b/ntex-server/src/signals.rs index 7e7be74c..c61f7790 100644 --- a/ntex-server/src/signals.rs +++ b/ntex-server/src/signals.rs @@ -1,4 +1,4 @@ -use std::{cell::RefCell, thread}; +use std::{cell::RefCell, sync::Mutex, thread}; use ntex_rt::System; @@ -8,6 +8,9 @@ thread_local! { static HANDLERS: RefCell>> = Default::default(); } +type CB = Box; +static CUR_SYS: Mutex>> = Mutex::new(RefCell::new(None)); + /// Different types of process signals #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum Signal { @@ -34,49 +37,73 @@ pub fn signal() -> oneshot::Receiver { rx } +fn register_system(srv: Server) -> bool { + let guard = match CUR_SYS.lock() { + Ok(guard) => guard, + Err(_) => { + log::error!("Cannot lock mutex"); + return true; + } + }; + + let mut sys = guard.borrow_mut(); + let started = sys.is_some(); + *sys = Some((System::current(), Box::new(move |sig| srv.signal(sig)))); + started +} + +fn handle_signal(sig: Signal) { + if let Ok(guard) = CUR_SYS.lock() { + if let Some((sys, srv)) = &*guard.borrow() { + (*srv)(sig); + sys.arbiter().exec_fn(move || { + HANDLERS.with(|handlers| { + for tx in handlers.borrow_mut().drain(..) { + let _ = tx.send(sig); + } + }) + }); + } + } +} + #[cfg(target_family = "unix")] /// Register signal handler. /// /// Signals are handled by oneshots, you have to re-register /// after each signal. pub(crate) fn start(srv: Server) { - let _ = thread::Builder::new() - .name("ntex-server signals".to_string()) - .spawn(move || { - use signal_hook::consts::signal::*; - use signal_hook::iterator::Signals; + if !register_system(srv) { + let _ = thread::Builder::new() + .name("ntex-server signals".to_string()) + .spawn(move || { + use signal_hook::consts::signal::*; + use signal_hook::iterator::Signals; - let sigs = vec![SIGHUP, SIGINT, SIGTERM, SIGQUIT]; - let mut signals = match Signals::new(sigs) { - Ok(signals) => signals, - Err(e) => { - log::error!("Cannot initialize signals handler: {}", e); - return; - } - }; - for info in &mut signals { - let sig = match info { - SIGHUP => Signal::Hup, - SIGTERM => Signal::Term, - SIGINT => Signal::Int, - SIGQUIT => Signal::Quit, - _ => continue, + let sigs = vec![SIGHUP, SIGINT, SIGTERM, SIGQUIT]; + let mut signals = match Signals::new(sigs) { + Ok(signals) => signals, + Err(e) => { + log::error!("Cannot initialize signals handler: {}", e); + return; + } }; + for info in &mut signals { + let sig = match info { + SIGHUP => Signal::Hup, + SIGTERM => Signal::Term, + SIGINT => Signal::Int, + SIGQUIT => Signal::Quit, + _ => continue, + }; + handle_signal(sig); - srv.signal(sig); - System::current().arbiter().exec_fn(move || { - HANDLERS.with(|handlers| { - for tx in handlers.borrow_mut().drain(..) { - let _ = tx.send(sig); - } - }) - }); - - if matches!(sig, Signal::Int | Signal::Quit) { - return; + if matches!(sig, Signal::Int | Signal::Quit) { + return; + } } - } - }); + }); + } } #[cfg(target_family = "windows")] @@ -85,49 +112,12 @@ pub(crate) fn start(srv: Server) { /// Signals are handled by oneshots, you have to re-register /// after each signal. pub(crate) fn start(srv: Server) { - use std::sync::Mutex; - - use ntex_rt::spawn; - - static CUR_SYS: Mutex>> = Mutex::new(RefCell::new(None)); - - let guard = match CUR_SYS.lock() { - Ok(guard) => guard, - Err(_) => { - log::error!("Cannot lock mutex"); - return; - } - }; - - let mut sys = guard.borrow_mut(); - let started = sys.is_some(); - *sys = Some(System::current()); - - let rx = signal(); - let _ = spawn(async move { - if let Ok(sig) = rx.await { - srv.signal(sig); - } - }); - - if !started { + if !register_system(srv) { let _ = thread::Builder::new() .name("ntex-server signals".to_string()) .spawn(move || { - ctrlc::set_handler(move || { - if let Ok(guard) = CUR_SYS.lock() { - if let Some(sys) = &*guard.borrow() { - sys.arbiter().exec_fn(|| { - HANDLERS.with(|handlers| { - for tx in handlers.borrow_mut().drain(..) { - let _ = tx.send(Signal::Int); - } - }) - }); - } - } - }) - .expect("Error setting Ctrl-C handler"); + ctrlc::set_handler(|| handle_signal(Signal::Int)) + .expect("Error setting Ctrl-C handler"); }); } }