◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
35 changes: 28 additions & 7 deletions crates/vm/src/signal.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use crate::{PyObjectRef, PyResult, VirtualMachine};
use alloc::fmt;
use core::cell::{Cell, RefCell};
use core::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc;

#[cfg(windows)]
Expand All @@ -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.
Expand Down Expand Up @@ -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) }
}
11 changes: 7 additions & 4 deletions crates/vm/src/stdlib/_signal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 core::{
ops::Range,
sync::atomic::{self, Ordering},
Expand Up @@ -193,7 +196,7 @@ pub(crate) mod _signal {
};

vm.signal_handlers
.get_or_init(signal::new_signal_handlers)
.borrow_mut()[signum as usize] = py_handler;
}

Expand Down Expand Up @@ -247,15 +250,15 @@ 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 old_handler = signal_handlers.borrow_mut()[signalnum as usize].replace(handler);
Ok(old_handler)
}

#[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 handler = signal_handlers.borrow()[signalnum as usize]
.clone()
.unwrap_or_else(|| vm.ctx.none());
Expand Down
2 changes: 1 addition & 1 deletion crates/vm/src/stdlib/posix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);

// Phase 4: Run Python-level at-fork callbacks.
let after_forkers_child: Vec<PyObjectRef> = vm.state.after_forkers_child.lock().clone();
Expand Down
Loading
Toggle all file notes Toggle all file annotations