55
66#include "Python.h"
77#include "pycore_atomic.h"
8+ #include "pycore_call.h"
89#include "pycore_ceval.h"
10+ #include "pycore_pyerrors.h"
911#include "pycore_pystate.h"
1012
1113#ifndef MS_WINDOWS
@@ -189,13 +191,6 @@ itimer_retval(struct itimerval *iv)
189191}
190192#endif
191193
192- static int
193- thread_can_handle_signals (void )
194- {
195- PyThreadState * tstate = _PyThreadState_GET ();
196- return _Py_ThreadCanHandleSignals (tstate );
197- }
198-
199194static PyObject *
200195signal_default_int_handler (PyObject * self , PyObject * args )
201196{
@@ -480,43 +475,53 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
480475 }
481476#endif
482477
483- if (!thread_can_handle_signals ()) {
484- PyErr_SetString (PyExc_ValueError ,
485- "signal only works in main thread "
486- "of the main interpreter" );
478+ PyThreadState * tstate = _PyThreadState_GET ();
479+ if (!_Py_ThreadCanHandleSignals (tstate )) {
480+ _PyErr_SetString (tstate , PyExc_ValueError ,
481+ "signal only works in main thread "
482+ "of the main interpreter" );
487483 return NULL ;
488484 }
489485 if (signalnum < 1 || signalnum >= NSIG ) {
490- PyErr_SetString ( PyExc_ValueError ,
491- "signal number out of range" );
486+ _PyErr_SetString ( tstate , PyExc_ValueError ,
487+ "signal number out of range" );
492488 return NULL ;
493489 }
494- if (handler == IgnoreHandler )
490+ if (handler == IgnoreHandler ) {
495491 func = SIG_IGN ;
496- else if (handler == DefaultHandler )
492+ }
493+ else if (handler == DefaultHandler ) {
497494 func = SIG_DFL ;
495+ }
498496 else if (!PyCallable_Check (handler )) {
499- PyErr_SetString (PyExc_TypeError ,
500- "signal handler must be signal.SIG_IGN, signal.SIG_DFL, or a callable object" );
501- return NULL ;
497+ _PyErr_SetString (tstate , PyExc_TypeError ,
498+ "signal handler must be signal.SIG_IGN, "
499+ "signal.SIG_DFL, or a callable object" );
500+ return NULL ;
502501 }
503- else
502+ else {
504503 func = signal_handler ;
504+ }
505+
505506 /* Check for pending signals before changing signal handler */
506- if (_PyErr_CheckSignals ( )) {
507+ if (_PyErr_CheckSignalsTstate ( tstate )) {
507508 return NULL ;
508509 }
509510 if (PyOS_setsig (signalnum , func ) == SIG_ERR ) {
510511 PyErr_SetFromErrno (PyExc_OSError );
511512 return NULL ;
512513 }
514+
513515 old_handler = Handlers [signalnum ].func ;
514516 Py_INCREF (handler );
515517 Handlers [signalnum ].func = handler ;
516- if (old_handler != NULL )
518+
519+ if (old_handler != NULL ) {
517520 return old_handler ;
518- else
521+ }
522+ else {
519523 Py_RETURN_NONE ;
524+ }
520525}
521526
522527
@@ -698,10 +703,11 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
698703 return NULL ;
699704#endif
700705
701- if (!thread_can_handle_signals ()) {
702- PyErr_SetString (PyExc_ValueError ,
703- "set_wakeup_fd only works in main thread "
704- "of the main interpreter" );
706+ PyThreadState * tstate = _PyThreadState_GET ();
707+ if (!_Py_ThreadCanHandleSignals (tstate )) {
708+ _PyErr_SetString (tstate , PyExc_ValueError ,
709+ "set_wakeup_fd only works in main thread "
710+ "of the main interpreter" );
705711 return NULL ;
706712 }
707713
@@ -727,12 +733,13 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
727733
728734 fd = (int )sockfd ;
729735 if ((SOCKET_T )fd != sockfd ) {
730- PyErr_SetString ( PyExc_ValueError , "invalid fd" );
736+ _PyErr_SetString ( tstate , PyExc_ValueError , "invalid fd" );
731737 return NULL ;
732738 }
733739
734- if (_Py_fstat (fd , & status ) != 0 )
740+ if (_Py_fstat (fd , & status ) != 0 ) {
735741 return NULL ;
742+ }
736743
737744 /* on Windows, a file cannot be set to non-blocking mode */
738745 }
@@ -764,9 +771,9 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
764771 if (blocking < 0 )
765772 return NULL ;
766773 if (blocking ) {
767- PyErr_Format ( PyExc_ValueError ,
768- "the fd %i must be in non-blocking mode" ,
769- fd );
774+ _PyErr_Format ( tstate , PyExc_ValueError ,
775+ "the fd %i must be in non-blocking mode" ,
776+ fd );
770777 return NULL ;
771778 }
772779 }
@@ -1673,23 +1680,22 @@ finisignal(void)
16731680int
16741681PyErr_CheckSignals (void )
16751682{
1676- if (!thread_can_handle_signals ()) {
1683+ PyThreadState * tstate = _PyThreadState_GET ();
1684+ if (!_Py_ThreadCanHandleSignals (tstate )) {
16771685 return 0 ;
16781686 }
16791687
1680- return _PyErr_CheckSignals ( );
1688+ return _PyErr_CheckSignalsTstate ( tstate );
16811689}
16821690
16831691
16841692/* Declared in cpython/pyerrors.h */
16851693int
1686- _PyErr_CheckSignals ( void )
1694+ _PyErr_CheckSignalsTstate ( PyThreadState * tstate )
16871695{
1688- int i ;
1689- PyObject * f ;
1690-
1691- if (!_Py_atomic_load (& is_tripped ))
1696+ if (!_Py_atomic_load (& is_tripped )) {
16921697 return 0 ;
1698+ }
16931699
16941700 /*
16951701 * The is_tripped variable is meant to speed up the calls to
@@ -1707,32 +1713,48 @@ _PyErr_CheckSignals(void)
17071713 */
17081714 _Py_atomic_store (& is_tripped , 0 );
17091715
1710- if (!(f = (PyObject * )PyEval_GetFrame ()))
1711- f = Py_None ;
1716+ PyObject * frame = (PyObject * )tstate -> frame ;
1717+ if (!frame ) {
1718+ frame = Py_None ;
1719+ }
17121720
1713- for (i = 1 ; i < NSIG ; i ++ ) {
1714- if (_Py_atomic_load_relaxed (& Handlers [i ].tripped )) {
1715- PyObject * result = NULL ;
1716- PyObject * arglist = Py_BuildValue ("(iO)" , i , f );
1717- _Py_atomic_store_relaxed (& Handlers [i ].tripped , 0 );
1718-
1719- if (arglist ) {
1720- result = PyObject_Call (Handlers [i ].func , arglist , NULL );
1721- Py_DECREF (arglist );
1722- }
1723- if (!result ) {
1724- _Py_atomic_store (& is_tripped , 1 );
1725- return -1 ;
1726- }
1721+ for (int i = 1 ; i < NSIG ; i ++ ) {
1722+ if (!_Py_atomic_load_relaxed (& Handlers [i ].tripped )) {
1723+ continue ;
1724+ }
1725+ _Py_atomic_store_relaxed (& Handlers [i ].tripped , 0 );
17271726
1728- Py_DECREF (result );
1727+ PyObject * arglist = Py_BuildValue ("(iO)" , i , frame );
1728+ PyObject * result ;
1729+ if (arglist ) {
1730+ result = _PyObject_Call (tstate , Handlers [i ].func , arglist , NULL );
1731+ Py_DECREF (arglist );
1732+ }
1733+ else {
1734+ result = NULL ;
1735+ }
1736+ if (!result ) {
1737+ /* On error, re-schedule a call to _PyErr_CheckSignalsTstate() */
1738+ _Py_atomic_store (& is_tripped , 1 );
1739+ return -1 ;
17291740 }
1741+
1742+ Py_DECREF (result );
17301743 }
17311744
17321745 return 0 ;
17331746}
17341747
17351748
1749+
1750+ int
1751+ _PyErr_CheckSignals (void )
1752+ {
1753+ PyThreadState * tstate = _PyThreadState_GET ();
1754+ return _PyErr_CheckSignalsTstate (tstate );
1755+ }
1756+
1757+
17361758/* Simulate the effect of a signal.SIGINT signal arriving. The next time
17371759 PyErr_CheckSignals is called, the Python SIGINT signal handler will be
17381760 raised.
@@ -1765,14 +1787,17 @@ PyOS_FiniInterrupts(void)
17651787int
17661788PyOS_InterruptOccurred (void )
17671789{
1768- if (_Py_atomic_load_relaxed (& Handlers [SIGINT ].tripped )) {
1769- if (!thread_can_handle_signals ()) {
1770- return 0 ;
1771- }
1772- _Py_atomic_store_relaxed (& Handlers [SIGINT ].tripped , 0 );
1773- return 1 ;
1790+ PyThreadState * tstate = _PyThreadState_GET ();
1791+ if (!_Py_ThreadCanHandleSignals (tstate )) {
1792+ return 0 ;
17741793 }
1775- return 0 ;
1794+
1795+ if (!_Py_atomic_load_relaxed (& Handlers [SIGINT ].tripped )) {
1796+ return 0 ;
1797+ }
1798+
1799+ _Py_atomic_store_relaxed (& Handlers [SIGINT ].tripped , 0 );
1800+ return 1 ;
17761801}
17771802
17781803static void
@@ -1799,7 +1824,8 @@ _PySignal_AfterFork(void)
17991824int
18001825_PyOS_IsMainThread (void )
18011826{
1802- return thread_can_handle_signals ();
1827+ PyThreadState * tstate = _PyThreadState_GET ();
1828+ return _Py_ThreadCanHandleSignals (tstate );
18031829}
18041830
18051831#ifdef MS_WINDOWS
0 commit comments