forked from Rust-related/RustPython
split signal module from stdlib
This commit is contained in:
@@ -69,6 +69,7 @@ mod pyobjectrc;
|
||||
pub mod readline;
|
||||
pub mod scope;
|
||||
mod sequence;
|
||||
mod signal;
|
||||
mod sliceable;
|
||||
pub mod slots;
|
||||
pub mod stdlib;
|
||||
|
||||
43
vm/src/signal.rs
Normal file
43
vm/src/signal.rs
Normal file
@@ -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<PyObjectRef>; 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(())
|
||||
}
|
||||
@@ -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<PyObjectRef>; 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(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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")]
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user