@@ -177,6 +177,17 @@ get_signal_state(PyObject *module)
177
177
}
178
178
179
179
180
+ static inline int
181
+ compare_handler (PyObject * handler , PyObject * func )
182
+ {
183
+ assert (PyLong_CheckExact (handler ));
184
+ if (!PyLong_CheckExact (func )) {
185
+ return 0 ;
186
+ }
187
+ // Assume that comparison of two PyLong objects will never fail.
188
+ return PyObject_RichCompareBool (func , handler , Py_EQ ) == 1 ;
189
+ }
190
+
180
191
#ifdef HAVE_GETITIMER
181
192
/* auxiliary functions for setitimer */
182
193
static int
@@ -496,7 +507,6 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
496
507
_signal_module_state * modstate = get_signal_state (module );
497
508
PyObject * old_handler ;
498
509
void (* func )(int );
499
- int match = 0 ; // cannot use func == NULL as sentinel, SIG_DFL == 0
500
510
#ifdef MS_WINDOWS
501
511
/* Validate that signalnum is one of the allowable signals */
502
512
switch (signalnum ) {
@@ -531,31 +541,11 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
531
541
}
532
542
if (PyCallable_Check (handler )) {
533
543
func = signal_handler ;
534
- match = 1 ;
535
- }
536
- if (!match ) {
537
- int cmp = PyObject_RichCompareBool (handler , modstate -> ignore_handler , Py_EQ );
538
- switch (cmp ) {
539
- case -1 :
540
- return NULL ;
541
- case 1 :
542
- func = SIG_IGN ;
543
- match = 1 ;
544
- break ;
545
- }
546
- }
547
- if (!match ) {
548
- int cmp = PyObject_RichCompareBool (handler , modstate -> default_handler , Py_EQ );
549
- switch (cmp ) {
550
- case -1 :
551
- return NULL ;
552
- case 1 :
553
- func = SIG_DFL ;
554
- match = 1 ;
555
- break ;
556
- }
557
- }
558
- if (!match ) {
544
+ } else if (compare_handler (handler , modstate -> ignore_handler )) {
545
+ func = SIG_IGN ;
546
+ } else if (compare_handler (handler , modstate -> default_handler )) {
547
+ func = SIG_DFL ;
548
+ } else {
559
549
_PyErr_SetString (tstate , PyExc_TypeError ,
560
550
"signal handler must be signal.SIG_IGN, "
561
551
"signal.SIG_DFL, or a callable object" );
@@ -1770,8 +1760,8 @@ _PySignal_Fini(void)
1770
1760
set_handler (signum , NULL );
1771
1761
if (func != NULL
1772
1762
&& func != Py_None
1773
- && func != state -> default_handler
1774
- && func != state -> ignore_handler )
1763
+ && ! compare_handler ( func , state -> default_handler )
1764
+ && ! compare_handler ( func , state -> ignore_handler ) )
1775
1765
{
1776
1766
PyOS_setsig (signum , SIG_DFL );
1777
1767
}
@@ -1842,8 +1832,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
1842
1832
* (see bpo-43406).
1843
1833
*/
1844
1834
PyObject * func = get_handler (i );
1845
- if (func == NULL || func == Py_None || func == state -> ignore_handler ||
1846
- func == state -> default_handler ) {
1835
+ if (func == NULL || func == Py_None ||
1836
+ compare_handler (func , state -> ignore_handler ) ||
1837
+ compare_handler (func , state -> default_handler )) {
1847
1838
/* No Python signal handler due to aforementioned race condition.
1848
1839
* We can't call raise() as it would break the assumption
1849
1840
* that PyErr_SetInterrupt() only *simulates* an incoming
@@ -1911,15 +1902,8 @@ PyErr_SetInterruptEx(int signum)
1911
1902
1912
1903
signal_state_t * state = & signal_global_state ;
1913
1904
PyObject * func = get_handler (signum );
1914
- int is_ign = PyObject_RichCompareBool (func , state -> ignore_handler , Py_EQ );
1915
- if (is_ign == -1 ) {
1916
- return -1 ;
1917
- }
1918
- int is_dfl = PyObject_RichCompareBool (func , state -> default_handler , Py_EQ );
1919
- if (is_dfl == -1 ) {
1920
- return -1 ;
1921
- }
1922
- if ((is_ign == 0 ) && (is_dfl == 0 )) {
1905
+ if (!compare_handler (func , state -> ignore_handler )
1906
+ && !compare_handler (func , state -> default_handler )) {
1923
1907
trip_signal (signum );
1924
1908
}
1925
1909
return 0 ;
0 commit comments