bpo-40010: COMPUTE_EVAL_BREAKER() checks for subinterpreter (GH-19087)

COMPUTE_EVAL_BREAKER() now also checks if the Python thread state
belongs to the main interpreter. Don't break the evaluation loop if
there are pending signals but the Python thread state it belongs to a
subinterpeter.

* Add _Py_IsMainThread() function.
* Add _Py_ThreadCanHandleSignals() function.
This commit is contained in:
Victor Stinner 2020-03-20 13:38:58 +01:00 committed by GitHub
parent da2914db4b
commit d2a8e5b42c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 53 deletions

View file

@ -190,12 +190,10 @@ itimer_retval(struct itimerval *iv)
#endif
static int
is_main(_PyRuntimeState *runtime)
thread_can_handle_signals(void)
{
unsigned long thread = PyThread_get_thread_ident();
PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
return (thread == runtime->main_thread
&& interp == runtime->interpreters.main);
PyThreadState *tstate = _PyThreadState_GET();
return _Py_ThreadCanHandleSignals(tstate);
}
static PyObject *
@ -482,10 +480,10 @@ signal_signal_impl(PyObject *module, int signalnum, PyObject *handler)
}
#endif
_PyRuntimeState *runtime = &_PyRuntime;
if (!is_main(runtime)) {
if (!thread_can_handle_signals()) {
PyErr_SetString(PyExc_ValueError,
"signal only works in main thread");
"signal only works in main thread "
"of the main interpreter");
return NULL;
}
if (signalnum < 1 || signalnum >= NSIG) {
@ -700,10 +698,10 @@ signal_set_wakeup_fd(PyObject *self, PyObject *args, PyObject *kwds)
return NULL;
#endif
_PyRuntimeState *runtime = &_PyRuntime;
if (!is_main(runtime)) {
if (!thread_can_handle_signals()) {
PyErr_SetString(PyExc_ValueError,
"set_wakeup_fd only works in main thread");
"set_wakeup_fd only works in main thread "
"of the main interpreter");
return NULL;
}
@ -1675,8 +1673,7 @@ finisignal(void)
int
PyErr_CheckSignals(void)
{
_PyRuntimeState *runtime = &_PyRuntime;
if (!is_main(runtime)) {
if (!thread_can_handle_signals()) {
return 0;
}
@ -1769,8 +1766,7 @@ int
PyOS_InterruptOccurred(void)
{
if (_Py_atomic_load_relaxed(&Handlers[SIGINT].tripped)) {
_PyRuntimeState *runtime = &_PyRuntime;
if (!is_main(runtime)) {
if (!thread_can_handle_signals()) {
return 0;
}
_Py_atomic_store_relaxed(&Handlers[SIGINT].tripped, 0);
@ -1803,8 +1799,7 @@ _PySignal_AfterFork(void)
int
_PyOS_IsMainThread(void)
{
_PyRuntimeState *runtime = &_PyRuntime;
return is_main(runtime);
return thread_can_handle_signals();
}
#ifdef MS_WINDOWS