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

@ -294,7 +294,33 @@ _PyRuntimeState_SetFinalizing(_PyRuntimeState *runtime, PyThreadState *tstate) {
_Py_atomic_store_relaxed(&runtime->_finalizing, (uintptr_t)tstate);
}
PyAPI_FUNC(int) _Py_IsMainInterpreter(PyThreadState* tstate);
/* Check if the current thread is the main thread.
Use _Py_IsMainInterpreter() to check if it's the main interpreter. */
static inline int
_Py_IsMainThread(void)
{
unsigned long thread = PyThread_get_thread_ident();
return (thread == _PyRuntime.main_thread);
}
static inline int
_Py_IsMainInterpreter(PyThreadState* tstate)
{
/* Use directly _PyRuntime rather than tstate->interp->runtime, since
this function is used in performance critical code path (ceval) */
return (tstate->interp == _PyRuntime.interpreters.main);
}
/* Only handle signals on the main thread of the main interpreter. */
static inline int
_Py_ThreadCanHandleSignals(PyThreadState *tstate)
{
/* Use directly _PyRuntime rather than tstate->interp->runtime, since
this function is used in performance critical code path (ceval) */
return (_Py_IsMainThread() && _Py_IsMainInterpreter(tstate));
}
/* Variable and macro for in-line access to current thread