Skip to content

Commit 9d5dde5

Browse files
[3.13] gh-122201: Lock mutex when setting handling_thread to NULL (GH-122204) (#122319)
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. (cherry picked from commit c557ae9) Co-authored-by: Sam Gross <[email protected]>
1 parent 816a157 commit 9d5dde5

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

Python/ceval_gil.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,18 @@ unsignal_pending_calls(PyThreadState *tstate, PyInterpreterState *interp)
901901
#endif
902902
}
903903

904+
static void
905+
clear_pending_handling_thread(struct _pending_calls *pending)
906+
{
907+
#ifdef Py_GIL_DISABLED
908+
PyMutex_Lock(&pending->mutex);
909+
pending->handling_thread = NULL;
910+
PyMutex_Unlock(&pending->mutex);
911+
#else
912+
pending->handling_thread = NULL;
913+
#endif
914+
}
915+
904916
static int
905917
make_pending_calls(PyThreadState *tstate)
906918
{
@@ -933,7 +945,7 @@ make_pending_calls(PyThreadState *tstate)
933945

934946
int32_t npending;
935947
if (_make_pending_calls(pending, &npending) != 0) {
936-
pending->handling_thread = NULL;
948+
clear_pending_handling_thread(pending);
937949
/* There might not be more calls to make, but we play it safe. */
938950
signal_pending_calls(tstate, interp);
939951
return -1;
@@ -945,7 +957,7 @@ make_pending_calls(PyThreadState *tstate)
945957

946958
if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) {
947959
if (_make_pending_calls(pending_main, &npending) != 0) {
948-
pending->handling_thread = NULL;
960+
clear_pending_handling_thread(pending);
949961
/* There might not be more calls to make, but we play it safe. */
950962
signal_pending_calls(tstate, interp);
951963
return -1;
@@ -956,7 +968,7 @@ make_pending_calls(PyThreadState *tstate)
956968
}
957969
}
958970

959-
pending->handling_thread = NULL;
971+
clear_pending_handling_thread(pending);
960972
return 0;
961973
}
962974

Tools/tsan/suppressions_free_threading.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ race_top:assign_version_tag
2828
race_top:new_reference
2929
race_top:_multiprocessing_SemLock_acquire_impl
3030
race_top:list_get_item_ref
31-
race_top:make_pending_calls
3231
race_top:_Py_slot_tp_getattr_hook
3332
race_top:add_threadstate
3433
race_top:dump_traceback

0 commit comments

Comments
 (0)