mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 03:04:38 +08:00
Newtype SignalHandlers (#8089)
This commit is contained in:
1 parent
f34cfca1f3
commit
a895eeed00
4 files changed
+40
-15
No files matched your search
+28
-7
@@ -1,7 +1,10 @@
|
||||
use crate::{PyObjectRef, PyResult, VirtualMachine};
|
||||
use alloc::fmt;
|
||||
use core::cell::{Cell, RefCell};
|
||||
use core::sync::atomic::{AtomicBool, Ordering};
|
||||
use core::{
|
||||
cell::{Cell, RefCell},
|
||||
fmt,
|
||||
ops::{Deref, DerefMut},
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use std::sync::mpsc;
|
||||
|
||||
#[cfg(windows)]
|
||||
@@ -22,10 +25,6 @@ pub(crate) static TRIGGERS: [AtomicBool; NSIG] = [ATOMIC_FALSE; NSIG];
|
||||
#[cfg(windows)]
|
||||
static SIGINT_EVENT: AtomicIsize = AtomicIsize::new(0);
|
||||
|
||||
pub(crate) fn new_signal_handlers() -> Box<RefCell<[Option<PyObjectRef>; NSIG]>> {
|
||||
Box::new(const { RefCell::new([const { None }; NSIG]) })
|
||||
}
|
||||
|
||||
thread_local! {
|
||||
/// Prevent recursive signal handler invocation. When a Python signal
|
||||
/// handler is running, new signals are deferred until it completes.
|
||||
@@ -190,3 +189,25 @@ pub fn get_sigint_event() -> Option<isize> {
|
||||
let handle = SIGINT_EVENT.load(Ordering::Acquire);
|
||||
if handle == 0 { None } else { Some(handle) }
|
||||
}
|
||||
|
||||
pub struct SignalHandlers(Box<RefCell<[Option<PyObjectRef>; NSIG]>>);
|
||||
|
||||
impl Default for SignalHandlers {
|
||||
fn default() -> Self {
|
||||
Self(Box::new(const { RefCell::new([const { None }; NSIG]) }))
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for SignalHandlers {
|
||||
type Target = Box<RefCell<[Option<PyObjectRef>; NSIG]>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for SignalHandlers {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,10 @@ pub(crate) use _signal::module_def;
|
||||
pub(crate) mod _signal {
|
||||
#![allow(unreachable_pub)]
|
||||
|
||||
use crate::{Py, PyObjectRef, PyResult, VirtualMachine, signal};
|
||||
use crate::{
|
||||
Py, PyObjectRef, PyResult, VirtualMachine,
|
||||
signal::{self, SignalHandlers},
|
||||
};
|
||||
use core::{
|
||||
ops::Range,
|
||||
sync::atomic::{self, Ordering},
|
||||
@@ -193,7 +196,7 @@ pub(crate) mod _signal {
|
||||
};
|
||||
|
||||
vm.signal_handlers
|
||||
.get_or_init(signal::new_signal_handlers)
|
||||
.get_or_init(SignalHandlers::default)
|
||||
.borrow_mut()[signum as usize] = py_handler;
|
||||
}
|
||||
|
||||
@@ -247,7 +250,7 @@ pub(crate) mod _signal {
|
||||
unsafe { host_signal::install_handler(signalnum, sig_handler) }
|
||||
.map_err(|_| vm.new_os_error("Failed to set signal"))?;
|
||||
|
||||
let signal_handlers = vm.signal_handlers.get_or_init(signal::new_signal_handlers);
|
||||
let signal_handlers = vm.signal_handlers.get_or_init(SignalHandlers::default);
|
||||
let old_handler = signal_handlers.borrow_mut()[signalnum as usize].replace(handler);
|
||||
Ok(old_handler)
|
||||
}
|
||||
@@ -255,7 +258,7 @@ pub(crate) mod _signal {
|
||||
#[pyfunction]
|
||||
fn getsignal(signalnum: i32, vm: &VirtualMachine) -> PyResult {
|
||||
signal::assert_in_range(signalnum, vm)?;
|
||||
let signal_handlers = vm.signal_handlers.get_or_init(signal::new_signal_handlers);
|
||||
let signal_handlers = vm.signal_handlers.get_or_init(SignalHandlers::default);
|
||||
let handler = signal_handlers.borrow()[signalnum as usize]
|
||||
.clone()
|
||||
.unwrap_or_else(|| vm.ctx.none());
|
||||
|
||||
@@ -670,7 +670,7 @@ pub mod module {
|
||||
// Initialize signal handlers for the child's main thread.
|
||||
// When forked from a worker thread, the OnceCell is empty.
|
||||
vm.signal_handlers
|
||||
.get_or_init(crate::signal::new_signal_handlers);
|
||||
.get_or_init(crate::signal::SignalHandlers::default);
|
||||
|
||||
// Phase 4: Run Python-level at-fork callbacks.
|
||||
let after_forkers_child: Vec<PyObjectRef> = vm.state.after_forkers_child.lock().clone();
|
||||
|
||||
@@ -36,7 +36,8 @@ use crate::{
|
||||
import,
|
||||
protocol::PyIterIter,
|
||||
scope::Scope,
|
||||
signal, stdlib,
|
||||
signal::{self, SignalHandlers},
|
||||
stdlib,
|
||||
warn::WarningsState,
|
||||
};
|
||||
use alloc::{borrow::Cow, collections::BTreeMap};
|
||||
@@ -82,7 +83,7 @@ pub struct VirtualMachine {
|
||||
pub trace_func: RefCell<PyObjectRef>,
|
||||
pub use_tracing: Cell<bool>,
|
||||
pub recursion_limit: Cell<usize>,
|
||||
pub(crate) signal_handlers: OnceCell<Box<RefCell<[Option<PyObjectRef>; signal::NSIG]>>>,
|
||||
pub(crate) signal_handlers: OnceCell<SignalHandlers>,
|
||||
pub(crate) signal_rx: Option<signal::UserSignalReceiver>,
|
||||
pub repr_guards: RefCell<HashSet<usize>>,
|
||||
pub state: PyRc<PyGlobalState>,
|
||||
@@ -723,7 +724,7 @@ impl VirtualMachine {
|
||||
let importlib = ctx.none();
|
||||
let profile_func = RefCell::new(ctx.none());
|
||||
let trace_func = RefCell::new(ctx.none());
|
||||
let signal_handlers = OnceCell::from(signal::new_signal_handlers());
|
||||
let signal_handlers = OnceCell::from(SignalHandlers::default());
|
||||
|
||||
let vm = Self {
|
||||
builtins,
|
||||
|
||||
Reference in new issue
Block a user