mirror of https://github.com/python/cpython
gh-122201: Lock mutex when setting handling_thread to NULL (#122204)
In the free-threaded build, we need to lock pending->mutex when clearing the handling_thread in order not to race with a concurrent make_pending_calls in the same interpreter.
This commit is contained in:
parent
64857d849f
commit
c557ae97d6
|
@ -901,6 +901,18 @@ unsignal_pending_calls(PyThreadState *tstate, PyInterpreterState *interp)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clear_pending_handling_thread(struct _pending_calls *pending)
|
||||||
|
{
|
||||||
|
#ifdef Py_GIL_DISABLED
|
||||||
|
PyMutex_Lock(&pending->mutex);
|
||||||
|
pending->handling_thread = NULL;
|
||||||
|
PyMutex_Unlock(&pending->mutex);
|
||||||
|
#else
|
||||||
|
pending->handling_thread = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
make_pending_calls(PyThreadState *tstate)
|
make_pending_calls(PyThreadState *tstate)
|
||||||
{
|
{
|
||||||
|
@ -933,7 +945,7 @@ make_pending_calls(PyThreadState *tstate)
|
||||||
|
|
||||||
int32_t npending;
|
int32_t npending;
|
||||||
if (_make_pending_calls(pending, &npending) != 0) {
|
if (_make_pending_calls(pending, &npending) != 0) {
|
||||||
pending->handling_thread = NULL;
|
clear_pending_handling_thread(pending);
|
||||||
/* There might not be more calls to make, but we play it safe. */
|
/* There might not be more calls to make, but we play it safe. */
|
||||||
signal_pending_calls(tstate, interp);
|
signal_pending_calls(tstate, interp);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -945,7 +957,7 @@ make_pending_calls(PyThreadState *tstate)
|
||||||
|
|
||||||
if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) {
|
if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) {
|
||||||
if (_make_pending_calls(pending_main, &npending) != 0) {
|
if (_make_pending_calls(pending_main, &npending) != 0) {
|
||||||
pending->handling_thread = NULL;
|
clear_pending_handling_thread(pending);
|
||||||
/* There might not be more calls to make, but we play it safe. */
|
/* There might not be more calls to make, but we play it safe. */
|
||||||
signal_pending_calls(tstate, interp);
|
signal_pending_calls(tstate, interp);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -956,7 +968,7 @@ make_pending_calls(PyThreadState *tstate)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pending->handling_thread = NULL;
|
clear_pending_handling_thread(pending);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,6 @@ race_top:assign_version_tag
|
||||||
race_top:new_reference
|
race_top:new_reference
|
||||||
race_top:_multiprocessing_SemLock_acquire_impl
|
race_top:_multiprocessing_SemLock_acquire_impl
|
||||||
race_top:list_get_item_ref
|
race_top:list_get_item_ref
|
||||||
race_top:make_pending_calls
|
|
||||||
race_top:_Py_slot_tp_getattr_hook
|
race_top:_Py_slot_tp_getattr_hook
|
||||||
race_top:add_threadstate
|
race_top:add_threadstate
|
||||||
race_top:dump_traceback
|
race_top:dump_traceback
|
||||||
|
|
Loading…
Reference in New Issue