@@ -177,6 +177,17 @@ get_signal_state(PyObject *module)
177177}
178178
179179
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+
180191#ifdef HAVE_GETITIMER
181192/* auxiliary functions for setitimer */
182193static int
@@ -496,7 +507,6 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
496507 _signal_module_state * modstate = get_signal_state (module );
497508 PyObject * old_handler ;
498509 void (* func )(int );
499- int match = 0 ; // cannot use func == NULL as sentinel, SIG_DFL == 0
500510#ifdef MS_WINDOWS
501511 /* Validate that signalnum is one of the allowable signals */
502512 switch (signalnum ) {
@@ -531,31 +541,11 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
531541 }
532542 if (PyCallable_Check (handler )) {
533543 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 {
559549 _PyErr_SetString (tstate , PyExc_TypeError ,
560550 "signal handler must be signal.SIG_IGN, "
561551 "signal.SIG_DFL, or a callable object" );
@@ -1770,8 +1760,8 @@ _PySignal_Fini(void)
17701760 set_handler (signum , NULL );
17711761 if (func != NULL
17721762 && 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 ) )
17751765 {
17761766 PyOS_setsig (signum , SIG_DFL );
17771767 }
@@ -1842,8 +1832,9 @@ _PyErr_CheckSignalsTstate(PyThreadState *tstate)
18421832 * (see bpo-43406).
18431833 */
18441834 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 )) {
18471838 /* No Python signal handler due to aforementioned race condition.
18481839 * We can't call raise() as it would break the assumption
18491840 * that PyErr_SetInterrupt() only *simulates* an incoming
@@ -1911,15 +1902,8 @@ PyErr_SetInterruptEx(int signum)
19111902
19121903 signal_state_t * state = & signal_global_state ;
19131904 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 )) {
19231907 trip_signal (signum );
19241908 }
19251909 return 0 ;
0 commit comments