From 1e9ec5b4b9944b32c3721c774a58ed5d8fccdfd2 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 28 Sep 2021 00:46:50 +0900 Subject: [PATCH] split signal module from stdlib --- vm/src/lib.rs | 1 + vm/src/signal.rs | 43 +++++++++++++++++++++ vm/src/stdlib/signal.rs | 84 +++++++++++------------------------------ vm/src/vm.rs | 5 +-- 4 files changed, 68 insertions(+), 65 deletions(-) create mode 100644 vm/src/signal.rs diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 4c8e15c255..7028c9e30d 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -69,6 +69,7 @@ mod pyobjectrc; pub mod readline; pub mod scope; mod sequence; +mod signal; mod sliceable; pub mod slots; pub mod stdlib; diff --git a/vm/src/signal.rs b/vm/src/signal.rs new file mode 100644 index 0000000000..a1aedf1b7c --- /dev/null +++ b/vm/src/signal.rs @@ -0,0 +1,43 @@ +use crate::{PyObjectRef, PyResult, VirtualMachine}; +use std::sync::atomic::{AtomicBool, Ordering}; + +pub const NSIG: usize = 64; +pub(crate) static ANY_TRIGGERED: AtomicBool = AtomicBool::new(false); +// hack to get around const array repeat expressions, rust issue #79270 +#[allow(clippy::declare_interior_mutable_const)] +const ATOMIC_FALSE: AtomicBool = AtomicBool::new(false); +pub(crate) static TRIGGERS: [AtomicBool; NSIG] = [ATOMIC_FALSE; NSIG]; + +#[cfg_attr(feature = "flame-it", flame)] +#[inline(always)] +pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> { + let signal_handlers = match &vm.signal_handlers { + Some(h) => h, + None => return Ok(()), + }; + + if !ANY_TRIGGERED.load(Ordering::Relaxed) { + return Ok(()); + } + ANY_TRIGGERED.store(false, Ordering::Relaxed); + + trigger_signals(&signal_handlers.borrow(), vm) +} +#[inline(never)] +#[cold] +fn trigger_signals( + signal_handlers: &[Option; NSIG], + vm: &VirtualMachine, +) -> PyResult<()> { + for (signum, trigger) in TRIGGERS.iter().enumerate().skip(1) { + let triggered = trigger.swap(false, Ordering::Relaxed); + if triggered { + if let Some(handler) = &signal_handlers[signum] { + if vm.is_callable(handler) { + vm.invoke(handler, (signum, vm.ctx.none()))?; + } + } + } + } + Ok(()) +} diff --git a/vm/src/stdlib/signal.rs b/vm/src/stdlib/signal.rs index d068a544a7..5a5f4e711c 100644 --- a/vm/src/stdlib/signal.rs +++ b/vm/src/stdlib/signal.rs @@ -1,8 +1,7 @@ use crate::{PyObjectRef, VirtualMachine}; -pub(crate) use _signal::check_signals; pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { - use crate::vm::NSIG; + use crate::signal::NSIG; use _signal::{SIG_DFL, SIG_ERR, SIG_IGN}; let module = _signal::make_module(vm); @@ -36,9 +35,27 @@ pub(crate) fn make_module(vm: &VirtualMachine) -> PyObjectRef { #[pymodule] pub(crate) mod _signal { use crate::{ - exceptions::IntoPyException, PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine, + exceptions::IntoPyException, + signal::{check_signals, ANY_TRIGGERED, TRIGGERS}, + PyObjectRef, PyResult, TryFromBorrowedObject, VirtualMachine, }; - use std::sync::atomic::{self, AtomicBool, Ordering}; + use std::sync::atomic::{self, Ordering}; + + cfg_if::cfg_if! { + if #[cfg(windows)] { + use winapi::um::winsock2; + type WakeupFd = libc::SOCKET; + const INVALID_WAKEUP: WakeupFd = (-1isize) as usize; + static WAKEUP: atomic::AtomicUsize = atomic::AtomicUsize::new(INVALID_WAKEUP); + // windows doesn't use the same fds for files and sockets like windows does, so we need + // this to know whether to send() or write() + static WAKEUP_IS_SOCKET: std::sync::atomic::AtomicBool = std::sync::atomic::AtomicBool::new(false); + } else { + type WakeupFd = i32; + const INVALID_WAKEUP: WakeupFd = -1; + static WAKEUP: atomic::AtomicI32 = atomic::AtomicI32::new(INVALID_WAKEUP); + } + } #[cfg(unix)] use nix::unistd::alarm as sig_alarm; @@ -59,36 +76,13 @@ pub(crate) mod _signal { #[cfg(windows)] pub const SIG_ERR: libc::sighandler_t = !0; - // hack to get around const array repeat expressions, rust issue #79270 - #[allow(clippy::declare_interior_mutable_const)] - const ATOMIC_FALSE: AtomicBool = AtomicBool::new(false); - static TRIGGERS: [AtomicBool; NSIG] = [ATOMIC_FALSE; NSIG]; - - static ANY_TRIGGERED: AtomicBool = AtomicBool::new(false); - - cfg_if::cfg_if! { - if #[cfg(windows)] { - use winapi::um::winsock2; - type WakeupFd = libc::SOCKET; - const INVALID_WAKEUP: WakeupFd = (-1isize) as usize; - static WAKEUP: atomic::AtomicUsize = atomic::AtomicUsize::new(INVALID_WAKEUP); - // windows doesn't use the same fds for files and sockets like windows does, so we need - // this to know whether to send() or write() - static WAKEUP_IS_SOCKET: AtomicBool = AtomicBool::new(false); - } else { - type WakeupFd = i32; - const INVALID_WAKEUP: WakeupFd = -1; - static WAKEUP: atomic::AtomicI32 = atomic::AtomicI32::new(INVALID_WAKEUP); - } - } - #[cfg(all(unix, not(target_os = "redox")))] extern "C" { fn siginterrupt(sig: i32, flag: i32) -> i32; } #[pyattr] - pub use crate::vm::NSIG; + pub use crate::signal::NSIG; #[pyattr] pub use libc::{SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM}; @@ -280,38 +274,4 @@ pub(crate) mod _signal { Err(vm.new_value_error("signal number out of range".to_owned())) } } - - #[cfg_attr(feature = "flame-it", flame)] - #[inline(always)] - pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> { - let signal_handlers = match &vm.signal_handlers { - Some(h) => h, - None => return Ok(()), - }; - - if !ANY_TRIGGERED.load(Ordering::Relaxed) { - return Ok(()); - } - ANY_TRIGGERED.store(false, Ordering::Relaxed); - - trigger_signals(&signal_handlers.borrow(), vm) - } - #[inline(never)] - #[cold] - fn trigger_signals( - signal_handlers: &[Option; NSIG], - vm: &VirtualMachine, - ) -> PyResult<()> { - for (signum, trigger) in TRIGGERS.iter().enumerate().skip(1) { - let triggered = trigger.swap(false, Ordering::Relaxed); - if triggered { - if let Some(handler) = &signal_handlers[signum] { - if vm.is_callable(handler) { - vm.invoke(handler, (signum, vm.ctx.none()))?; - } - } - } - } - Ok(()) - } } diff --git a/vm/src/vm.rs b/vm/src/vm.rs index a32e761237..c1700606ec 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -23,6 +23,7 @@ use crate::{ function::{FuncArgs, IntoFuncArgs}, import, iterator, scope::Scope, + signal::NSIG, slots::PyComparisonOp, stdlib, sysmodule, utils::Either, @@ -125,8 +126,6 @@ pub struct PyGlobalState { pub codec_registry: CodecsRegistry, } -pub const NSIG: usize = 64; - #[derive(Copy, Clone, PartialEq, Eq)] pub enum InitParameter { Internal, @@ -1549,7 +1548,7 @@ impl VirtualMachine { pub fn check_signals(&self) -> PyResult<()> { #[cfg(not(target_arch = "wasm32"))] { - crate::stdlib::signal::check_signals(self) + crate::signal::check_signals(self) } #[cfg(target_arch = "wasm32")] {