5
5
6
6
#include "Python.h"
7
7
#include "pycore_atomic.h"
8
+ #include "pycore_call.h"
8
9
#include "pycore_ceval.h"
10
+ #include "pycore_pyerrors.h"
9
11
#include "pycore_pystate.h"
10
12
11
13
#ifndef MS_WINDOWS
@@ -189,13 +191,6 @@ itimer_retval(struct itimerval *iv)
189
191
}
190
192
#endif
191
193
192
- static int
193
- thread_can_handle_signals (void )
194
- {
195
- PyThreadState * tstate = _PyThreadState_GET ();
196
- return _Py_ThreadCanHandleSignals (tstate );
197
- }
198
-
199
194
static PyObject *
200
195
signal_default_int_handler (PyObject * self , PyObject * args )
201
196
{
@@ -480,43 +475,53 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
480
475
}
481
476
#endif
482
477
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" );
487
483
return NULL ;
488
484
}
489
485
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" );
492
488
return NULL ;
493
489
}
494
- if (handler == IgnoreHandler )
490
+ if (handler == IgnoreHandler ) {
495
491
func = SIG_IGN ;
496
- else if (handler == DefaultHandler )
492
+ }
493
+ else if (handler == DefaultHandler ) {
497
494
func = SIG_DFL ;
495
+ }
498
496
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 ;
502
501
}
503
- else
502
+ else {
504
503
func = signal_handler ;
504
+ }
505
+
505
506
/* Check for pending signals before changing signal handler */
506
- if (_PyErr_CheckSignals ( )) {
507
+ if (_PyErr_CheckSignalsTstate ( tstate )) {
507
508
return NULL ;
508
509
}
509
510
if (PyOS_setsig (signalnum , func ) == SIG_ERR ) {
510
511
PyErr_SetFromErrno (PyExc_OSError );
511
512
return NULL ;
512
513
}
514
+
513
515
old_handler = Handlers [signalnum ].func ;
514
516
Py_INCREF (handler );
515
517
Handlers [signalnum ].func = handler ;
516
- if (old_handler != NULL )
518
+
519
+ if (old_handler != NULL ) {
517
520
return old_handler ;
518
- else
521
+ }
522
+ else {
519
523
Py_RETURN_NONE ;
524
+ }
520
525
}
521
526
522
527
@@ -698,10 +703,11 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
698
703
return NULL ;
699
704
#endif
700
705
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" );
705
711
return NULL ;
706
712
}
707
713
@@ -727,12 +733,13 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
727
733
728
734
fd = (int )sockfd ;
729
735
if ((SOCKET_T )fd != sockfd ) {
730
- PyErr_SetString ( PyExc_ValueError , "invalid fd" );
736
+ _PyErr_SetString ( tstate , PyExc_ValueError , "invalid fd" );
731
737
return NULL ;
732
738
}
733
739
734
- if (_Py_fstat (fd , & status ) != 0 )
740
+ if (_Py_fstat (fd , & status ) != 0 ) {
735
741
return NULL ;
742
+ }
736
743
737
744
/* on Windows, a file cannot be set to non-blocking mode */
738
745
}
@@ -764,9 +771,9 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
764
771
if (blocking < 0 )
765
772
return NULL ;
766
773
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 );
770
777
return NULL ;
771
778
}
772
779
}
@@ -1673,23 +1680,22 @@ finisignal(void)
1673
1680
int
1674
1681
PyErr_CheckSignals (void )
1675
1682
{
1676
- if (!thread_can_handle_signals ()) {
1683
+ PyThreadState * tstate = _PyThreadState_GET ();
1684
+ if (!_Py_ThreadCanHandleSignals (tstate )) {
1677
1685
return 0 ;
1678
1686
}
1679
1687
1680
- return _PyErr_CheckSignals ( );
1688
+ return _PyErr_CheckSignalsTstate ( tstate );
1681
1689
}
1682
1690
1683
1691
1684
1692
/* Declared in cpython/pyerrors.h */
1685
1693
int
1686
- _PyErr_CheckSignals ( void )
1694
+ _PyErr_CheckSignalsTstate ( PyThreadState * tstate )
1687
1695
{
1688
- int i ;
1689
- PyObject * f ;
1690
-
1691
- if (!_Py_atomic_load (& is_tripped ))
1696
+ if (!_Py_atomic_load (& is_tripped )) {
1692
1697
return 0 ;
1698
+ }
1693
1699
1694
1700
/*
1695
1701
* The is_tripped variable is meant to speed up the calls to
@@ -1707,32 +1713,48 @@ _PyErr_CheckSignals(void)
1707
1713
*/
1708
1714
_Py_atomic_store (& is_tripped , 0 );
1709
1715
1710
- if (!(f = (PyObject * )PyEval_GetFrame ()))
1711
- f = Py_None ;
1716
+ PyObject * frame = (PyObject * )tstate -> frame ;
1717
+ if (!frame ) {
1718
+ frame = Py_None ;
1719
+ }
1712
1720
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 );
1727
1726
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 ;
1729
1740
}
1741
+
1742
+ Py_DECREF (result );
1730
1743
}
1731
1744
1732
1745
return 0 ;
1733
1746
}
1734
1747
1735
1748
1749
+
1750
+ int
1751
+ _PyErr_CheckSignals (void )
1752
+ {
1753
+ PyThreadState * tstate = _PyThreadState_GET ();
1754
+ return _PyErr_CheckSignalsTstate (tstate );
1755
+ }
1756
+
1757
+
1736
1758
/* Simulate the effect of a signal.SIGINT signal arriving. The next time
1737
1759
PyErr_CheckSignals is called, the Python SIGINT signal handler will be
1738
1760
raised.
@@ -1765,14 +1787,17 @@ PyOS_FiniInterrupts(void)
1765
1787
int
1766
1788
PyOS_InterruptOccurred (void )
1767
1789
{
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 ;
1774
1793
}
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 ;
1776
1801
}
1777
1802
1778
1803
static void
@@ -1799,7 +1824,8 @@ _PySignal_AfterFork(void)
1799
1824
int
1800
1825
_PyOS_IsMainThread (void )
1801
1826
{
1802
- return thread_can_handle_signals ();
1827
+ PyThreadState * tstate = _PyThreadState_GET ();
1828
+ return _Py_ThreadCanHandleSignals (tstate );
1803
1829
}
1804
1830
1805
1831
#ifdef MS_WINDOWS
0 commit comments