summaryrefslogtreecommitdiffstats
path: root/Modules/signalmodule.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-04-08 21:35:05 (GMT)
committerGitHub <noreply@github.com>2020-04-08 21:35:05 (GMT)
commitb54a99d6432de93de85be2b42a63774f8b4581a0 (patch)
tree59e273ca69f89e6c7eedf91f458ee3cc50eb7cf8 /Modules/signalmodule.c
parentcfc3c2f8b34d3864717ab584c5b6c260014ba55a (diff)
downloadcpython-b54a99d6432de93de85be2b42a63774f8b4581a0.zip
cpython-b54a99d6432de93de85be2b42a63774f8b4581a0.tar.gz
cpython-b54a99d6432de93de85be2b42a63774f8b4581a0.tar.bz2
bpo-40082: trip_signal() uses the main interpreter (GH-19441)
Fix the signal handler: it now always uses the main interpreter, rather than trying to get the current Python thread state. The following function now accepts an interpreter, instead of a Python thread state: * _PyEval_SignalReceived() * _Py_ThreadCanHandleSignals() * _PyEval_AddPendingCall() * COMPUTE_EVAL_BREAKER() * SET_GIL_DROP_REQUEST(), RESET_GIL_DROP_REQUEST() * SIGNAL_PENDING_CALLS(), UNSIGNAL_PENDING_CALLS() * SIGNAL_PENDING_SIGNALS(), UNSIGNAL_PENDING_SIGNALS() * SIGNAL_ASYNC_EXC(), UNSIGNAL_ASYNC_EXC() Py_AddPendingCall() now uses the main interpreter if it fails to the current Python thread state. Convert _PyThreadState_GET() and PyInterpreterState_GET_UNSAFE() macros to static inline functions.
Diffstat (limited to 'Modules/signalmodule.c')
-rw-r--r--Modules/signalmodule.c27
1 files changed, 12 insertions, 15 deletions
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index 0a2c665..b089a80 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -252,14 +252,11 @@ trip_signal(int sig_num)
cleared in PyErr_CheckSignals() before .tripped. */
_Py_atomic_store(&is_tripped, 1);
- /* Get the Python thread state using PyGILState API, since
- _PyThreadState_GET() returns NULL if the GIL is released.
- For example, signal.raise_signal() releases the GIL. */
- PyThreadState *tstate = PyGILState_GetThisThreadState();
- assert(tstate != NULL);
+ /* Signals are always handled by the main interpreter */
+ PyInterpreterState *interp = _PyRuntime.interpreters.main;
/* Notify ceval.c */
- _PyEval_SignalReceived(tstate);
+ _PyEval_SignalReceived(interp);
/* And then write to the wakeup fd *after* setting all the globals and
doing the _PyEval_SignalReceived. We used to write to the wakeup fd
@@ -299,7 +296,7 @@ trip_signal(int sig_num)
{
/* _PyEval_AddPendingCall() isn't signal-safe, but we
still use it for this exceptional case. */
- _PyEval_AddPendingCall(tstate,
+ _PyEval_AddPendingCall(interp,
report_wakeup_send_error,
(void *)(intptr_t) last_error);
}
@@ -318,7 +315,7 @@ trip_signal(int sig_num)
{
/* _PyEval_AddPendingCall() isn't signal-safe, but we
still use it for this exceptional case. */
- _PyEval_AddPendingCall(tstate,
+ _PyEval_AddPendingCall(interp,
report_wakeup_write_error,
(void *)(intptr_t)errno);
}
@@ -476,7 +473,7 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
#endif
PyThreadState *tstate = _PyThreadState_GET();
- if (!_Py_ThreadCanHandleSignals(tstate)) {
+ if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
_PyErr_SetString(tstate, PyExc_ValueError,
"signal only works in main thread "
"of the main interpreter");
@@ -704,7 +701,7 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
#endif
PyThreadState *tstate = _PyThreadState_GET();
- if (!_Py_ThreadCanHandleSignals(tstate)) {
+ if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
_PyErr_SetString(tstate, PyExc_ValueError,
"set_wakeup_fd only works in main thread "
"of the main interpreter");
@@ -1681,7 +1678,7 @@ int
PyErr_CheckSignals(void)
{
PyThreadState *tstate = _PyThreadState_GET();
- if (!_Py_ThreadCanHandleSignals(tstate)) {
+ if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
return 0;
}
@@ -1787,8 +1784,8 @@ PyOS_FiniInterrupts(void)
int
PyOS_InterruptOccurred(void)
{
- PyThreadState *tstate = _PyThreadState_GET();
- if (!_Py_ThreadCanHandleSignals(tstate)) {
+ PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
+ if (!_Py_ThreadCanHandleSignals(interp)) {
return 0;
}
@@ -1824,8 +1821,8 @@ _PySignal_AfterFork(void)
int
_PyOS_IsMainThread(void)
{
- PyThreadState *tstate = _PyThreadState_GET();
- return _Py_ThreadCanHandleSignals(tstate);
+ PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
+ return _Py_ThreadCanHandleSignals(interp);
}
#ifdef MS_WINDOWS