@@ -3,8 +3,6 @@ use crate::vm::{VirtualMachine, NSIG};
33
44use std:: sync:: atomic:: { AtomicBool , Ordering } ;
55
6- use arr_macro:: arr;
7-
86#[ cfg( unix) ]
97use nix:: unistd:: alarm as sig_alarm;
108
@@ -18,8 +16,10 @@ const SIG_IGN: libc::sighandler_t = 1;
1816#[ cfg( windows) ]
1917const SIG_ERR : libc:: sighandler_t = !0 ;
2018
21- // We cannot use the NSIG const in the arr macro. This will fail compilation if NSIG is different.
22- static TRIGGERS : [ AtomicBool ; NSIG ] = arr ! [ AtomicBool :: new( false ) ; 64 ] ;
19+ // hack to get around const array repeat expressions, rust issue #79270
20+ #[ allow( clippy:: declare_interior_mutable_const) ]
21+ const ATOMIC_FALSE : AtomicBool = AtomicBool :: new ( false ) ;
22+ static TRIGGERS : [ AtomicBool ; NSIG ] = [ ATOMIC_FALSE ; NSIG ] ;
2323
2424static ANY_TRIGGERED : AtomicBool = AtomicBool :: new ( false ) ;
2525
@@ -36,11 +36,15 @@ fn assert_in_range(signum: i32, vm: &VirtualMachine) -> PyResult<()> {
3636 }
3737}
3838
39- fn _signal_signal ( signalnum : i32 , handler : PyObjectRef , vm : & VirtualMachine ) -> PyResult {
39+ fn _signal_signal (
40+ signalnum : i32 ,
41+ handler : PyObjectRef ,
42+ vm : & VirtualMachine ,
43+ ) -> PyResult < Option < PyObjectRef > > {
4044 assert_in_range ( signalnum, vm) ?;
4145 let signal_handlers = vm
4246 . signal_handlers
43- . as_ref ( )
47+ . as_deref ( )
4448 . ok_or_else ( || vm. new_value_error ( "signal only works in main thread" . to_owned ( ) ) ) ?;
4549
4650 let sig_handler = match usize:: try_from_object ( vm, handler. clone ( ) ) . ok ( ) {
@@ -70,10 +74,9 @@ fn _signal_signal(signalnum: i32, handler: PyObjectRef, vm: &VirtualMachine) ->
7074 }
7175 }
7276
73- let mut old_handler = handler;
74- std:: mem:: swap (
77+ let old_handler = std:: mem:: replace (
7578 & mut signal_handlers. borrow_mut ( ) [ signalnum as usize ] ,
76- & mut old_handler ,
79+ Some ( handler ) ,
7780 ) ;
7881 Ok ( old_handler)
7982}
@@ -82,9 +85,12 @@ fn _signal_getsignal(signalnum: i32, vm: &VirtualMachine) -> PyResult {
8285 assert_in_range ( signalnum, vm) ?;
8386 let signal_handlers = vm
8487 . signal_handlers
85- . as_ref ( )
88+ . as_deref ( )
8689 . ok_or_else ( || vm. new_value_error ( "getsignal only works in main thread" . to_owned ( ) ) ) ?;
87- Ok ( signal_handlers. borrow ( ) [ signalnum as usize ] . clone ( ) )
90+ let handler = signal_handlers. borrow ( ) [ signalnum as usize ]
91+ . clone ( )
92+ . unwrap_or_else ( || vm. ctx . none ( ) ) ;
93+ Ok ( handler)
8894}
8995
9096#[ cfg( unix) ]
@@ -113,13 +119,17 @@ pub fn check_signals(vm: &VirtualMachine) -> PyResult<()> {
113119}
114120#[ inline( never) ]
115121#[ cold]
116- fn trigger_signals ( signal_handlers : & [ PyObjectRef ; NSIG ] , vm : & VirtualMachine ) -> PyResult < ( ) > {
122+ fn trigger_signals (
123+ signal_handlers : & [ Option < PyObjectRef > ; NSIG ] ,
124+ vm : & VirtualMachine ,
125+ ) -> PyResult < ( ) > {
117126 for ( signum, trigger) in TRIGGERS . iter ( ) . enumerate ( ) . skip ( 1 ) {
118127 let triggerd = trigger. swap ( false , Ordering :: Relaxed ) ;
119128 if triggerd {
120- let handler = & signal_handlers[ signum] ;
121- if vm. is_callable ( handler) {
122- vm. invoke ( handler, ( signum, vm. ctx . none ( ) ) ) ?;
129+ if let Some ( handler) = & signal_handlers[ signum] {
130+ if vm. is_callable ( handler) {
131+ vm. invoke ( handler, ( signum, vm. ctx . none ( ) ) ) ?;
132+ }
123133 }
124134 }
125135 }
@@ -163,13 +173,13 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
163173 unsafe { libc:: signal ( signum as i32 , handler) } ;
164174 }
165175 let py_handler = if handler == SIG_DFL {
166- sig_dfl. clone ( )
176+ Some ( sig_dfl. clone ( ) )
167177 } else if handler == SIG_IGN {
168- sig_ign. clone ( )
178+ Some ( sig_ign. clone ( ) )
169179 } else {
170- vm . ctx . none ( )
180+ None
171181 } ;
172- vm. signal_handlers . as_ref ( ) . unwrap ( ) . borrow_mut ( ) [ signum] = py_handler;
182+ vm. signal_handlers . as_deref ( ) . unwrap ( ) . borrow_mut ( ) [ signum] = py_handler;
173183 }
174184
175185 _signal_signal ( libc:: SIGINT , int_handler, vm) . expect ( "Failed to set sigint handler" ) ;
0 commit comments