Skip to content

Commit 9198c26

Browse files
committed
Newtype SignalHandlers
1 parent d18d35f commit 9198c26

4 files changed

Lines changed: 40 additions & 15 deletions

File tree

crates/vm/src/signal.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use crate::{PyObjectRef, PyResult, VirtualMachine};
2-
use alloc::fmt;
3-
use core::cell::{Cell, RefCell};
4-
use core::sync::atomic::{AtomicBool, Ordering};
2+
use core::{
3+
cell::{Cell, RefCell},
4+
fmt,
5+
ops::{Deref, DerefMut},
6+
sync::atomic::{AtomicBool, Ordering},
7+
};
58
use std::sync::mpsc;
69

710
#[cfg(windows)]
@@ -22,10 +25,6 @@ pub(crate) static TRIGGERS: [AtomicBool; NSIG] = [ATOMIC_FALSE; NSIG];
2225
#[cfg(windows)]
2326
static SIGINT_EVENT: AtomicIsize = AtomicIsize::new(0);
2427

25-
pub(crate) fn new_signal_handlers() -> Box<RefCell<[Option<PyObjectRef>; NSIG]>> {
26-
Box::new(const { RefCell::new([const { None }; NSIG]) })
27-
}
28-
2928
thread_local! {
3029
/// Prevent recursive signal handler invocation. When a Python signal
3130
/// handler is running, new signals are deferred until it completes.
@@ -190,3 +189,25 @@ pub fn get_sigint_event() -> Option<isize> {
190189
let handle = SIGINT_EVENT.load(Ordering::Acquire);
191190
if handle == 0 { None } else { Some(handle) }
192191
}
192+
193+
pub struct SignalHandlers(Box<RefCell<[Option<PyObjectRef>; NSIG]>>);
194+
195+
impl Default for SignalHandlers {
196+
fn default() -> Self {
197+
Self(Box::new(const { RefCell::new([const { None }; NSIG]) }))
198+
}
199+
}
200+
201+
impl Deref for SignalHandlers {
202+
type Target = Box<RefCell<[Option<PyObjectRef>; NSIG]>>;
203+
204+
fn deref(&self) -> &Self::Target {
205+
&self.0
206+
}
207+
}
208+
209+
impl DerefMut for SignalHandlers {
210+
fn deref_mut(&mut self) -> &mut Self::Target {
211+
&mut self.0
212+
}
213+
}

crates/vm/src/stdlib/_signal.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ pub(crate) use _signal::module_def;
66
pub(crate) mod _signal {
77
#![allow(unreachable_pub)]
88

9-
use crate::{Py, PyObjectRef, PyResult, VirtualMachine, signal};
9+
use crate::{
10+
Py, PyObjectRef, PyResult, VirtualMachine,
11+
signal::{self, SignalHandlers},
12+
};
1013
use core::{
1114
ops::Range,
1215
sync::atomic::{self, Ordering},
@@ -193,7 +196,7 @@ pub(crate) mod _signal {
193196
};
194197

195198
vm.signal_handlers
196-
.get_or_init(signal::new_signal_handlers)
199+
.get_or_init(SignalHandlers::default)
197200
.borrow_mut()[signum as usize] = py_handler;
198201
}
199202

@@ -247,15 +250,15 @@ pub(crate) mod _signal {
247250
unsafe { host_signal::install_handler(signalnum, sig_handler) }
248251
.map_err(|_| vm.new_os_error("Failed to set signal"))?;
249252

250-
let signal_handlers = vm.signal_handlers.get_or_init(signal::new_signal_handlers);
253+
let signal_handlers = vm.signal_handlers.get_or_init(SignalHandlers::default);
251254
let old_handler = signal_handlers.borrow_mut()[signalnum as usize].replace(handler);
252255
Ok(old_handler)
253256
}
254257

255258
#[pyfunction]
256259
fn getsignal(signalnum: i32, vm: &VirtualMachine) -> PyResult {
257260
signal::assert_in_range(signalnum, vm)?;
258-
let signal_handlers = vm.signal_handlers.get_or_init(signal::new_signal_handlers);
261+
let signal_handlers = vm.signal_handlers.get_or_init(SignalHandlers::default);
259262
let handler = signal_handlers.borrow()[signalnum as usize]
260263
.clone()
261264
.unwrap_or_else(|| vm.ctx.none());

crates/vm/src/stdlib/posix.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ pub mod module {
670670
// Initialize signal handlers for the child's main thread.
671671
// When forked from a worker thread, the OnceCell is empty.
672672
vm.signal_handlers
673-
.get_or_init(crate::signal::new_signal_handlers);
673+
.get_or_init(crate::signal::SignalHandlers::default);
674674

675675
// Phase 4: Run Python-level at-fork callbacks.
676676
let after_forkers_child: Vec<PyObjectRef> = vm.state.after_forkers_child.lock().clone();

crates/vm/src/vm/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ use crate::{
3636
import,
3737
protocol::PyIterIter,
3838
scope::Scope,
39-
signal, stdlib,
39+
signal::{self, SignalHandlers},
40+
stdlib,
4041
warn::WarningsState,
4142
};
4243
use alloc::{borrow::Cow, collections::BTreeMap};
@@ -82,7 +83,7 @@ pub struct VirtualMachine {
8283
pub trace_func: RefCell<PyObjectRef>,
8384
pub use_tracing: Cell<bool>,
8485
pub recursion_limit: Cell<usize>,
85-
pub(crate) signal_handlers: OnceCell<Box<RefCell<[Option<PyObjectRef>; signal::NSIG]>>>,
86+
pub(crate) signal_handlers: OnceCell<SignalHandlers>,
8687
pub(crate) signal_rx: Option<signal::UserSignalReceiver>,
8788
pub repr_guards: RefCell<HashSet<usize>>,
8889
pub state: PyRc<PyGlobalState>,
@@ -723,7 +724,7 @@ impl VirtualMachine {
723724
let importlib = ctx.none();
724725
let profile_func = RefCell::new(ctx.none());
725726
let trace_func = RefCell::new(ctx.none());
726-
let signal_handlers = OnceCell::from(signal::new_signal_handlers());
727+
let signal_handlers = OnceCell::from(SignalHandlers::default());
727728

728729
let vm = Self {
729730
builtins,

0 commit comments

Comments
 (0)