mirror of
https://github.com/python/cpython.git
synced 2025-07-24 11:44:31 +00:00
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:
parent
da2914db4b
commit
d2a8e5b42c
5 changed files with 49 additions and 53 deletions
|
@ -136,14 +136,6 @@ is_tstate_valid(PyThreadState *tstate)
|
|||
#endif
|
||||
|
||||
|
||||
/* Only handle signals on the main thread of the main interpreter. */
|
||||
static int
|
||||
thread_can_handle_signals(void)
|
||||
{
|
||||
return (PyThread_get_thread_ident() == _PyRuntime.main_thread);
|
||||
}
|
||||
|
||||
|
||||
/* This can set eval_breaker to 0 even though gil_drop_request became
|
||||
1. We believe this is all right because the eval loop will release
|
||||
the GIL eventually anyway. */
|
||||
|
@ -156,7 +148,7 @@ COMPUTE_EVAL_BREAKER(PyThreadState *tstate,
|
|||
_Py_atomic_store_relaxed(&ceval2->eval_breaker,
|
||||
_Py_atomic_load_relaxed(&ceval->gil_drop_request)
|
||||
| (_Py_atomic_load_relaxed(&ceval->signals_pending)
|
||||
&& thread_can_handle_signals())
|
||||
&& _Py_ThreadCanHandleSignals(tstate))
|
||||
| _Py_atomic_load_relaxed(&ceval2->pending.calls_to_do)
|
||||
| ceval2->pending.async_exc);
|
||||
}
|
||||
|
@ -598,17 +590,7 @@ Py_AddPendingCall(int (*func)(void *), void *arg)
|
|||
static int
|
||||
handle_signals(PyThreadState *tstate)
|
||||
{
|
||||
_PyRuntimeState *runtime = tstate->interp->runtime;
|
||||
|
||||
if (!thread_can_handle_signals()) {
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Ensure that the thread isn't currently running some other
|
||||
* interpreter.
|
||||
*/
|
||||
PyInterpreterState *interp = tstate->interp;
|
||||
if (interp != runtime->interpreters.main) {
|
||||
if (!_Py_ThreadCanHandleSignals(tstate)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -624,11 +606,8 @@ handle_signals(PyThreadState *tstate)
|
|||
static int
|
||||
make_pending_calls(PyThreadState *tstate)
|
||||
{
|
||||
|
||||
_PyRuntimeState *runtime = tstate->interp->runtime;
|
||||
|
||||
/* only service pending calls on main thread */
|
||||
if (PyThread_get_thread_ident() != runtime->main_thread) {
|
||||
if (!_Py_IsMainThread()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,12 +169,6 @@ _PyRuntimeState_ReInitThreads(_PyRuntimeState *runtime)
|
|||
#define HEAD_UNLOCK(runtime) \
|
||||
PyThread_release_lock((runtime)->interpreters.mutex)
|
||||
|
||||
int
|
||||
_Py_IsMainInterpreter(PyThreadState* tstate)
|
||||
{
|
||||
return (tstate->interp == tstate->interp->runtime->interpreters.main);
|
||||
}
|
||||
|
||||
/* Forward declaration */
|
||||
static void _PyGILState_NoteThreadState(
|
||||
struct _gilstate_runtime_state *gilstate, PyThreadState* tstate);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue