summaryrefslogtreecommitdiffstats
path: root/Python/ceval_gil.c
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-07-26 17:06:07 (GMT)
committerGitHub <noreply@github.com>2024-07-26 17:06:07 (GMT)
commitc557ae97d6bd9d04164a19b4fe136610e54dbdd8 (patch)
tree918333ecf6b8ef6758c1a6b1c73c00a0e86a045b /Python/ceval_gil.c
parent64857d849f3079a73367525ce93fd7a463b83908 (diff)
downloadcpython-c557ae97d6bd9d04164a19b4fe136610e54dbdd8.zip
cpython-c557ae97d6bd9d04164a19b4fe136610e54dbdd8.tar.gz
cpython-c557ae97d6bd9d04164a19b4fe136610e54dbdd8.tar.bz2
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.
Diffstat (limited to 'Python/ceval_gil.c')
-rw-r--r--Python/ceval_gil.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c
index dc3baf7..0b45cab 100644
--- a/Python/ceval_gil.c
+++ b/Python/ceval_gil.c
@@ -901,6 +901,18 @@ unsignal_pending_calls(PyThreadState *tstate, PyInterpreterState *interp)
#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
make_pending_calls(PyThreadState *tstate)
{
@@ -933,7 +945,7 @@ make_pending_calls(PyThreadState *tstate)
int32_t npending;
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. */
signal_pending_calls(tstate, interp);
return -1;
@@ -945,7 +957,7 @@ make_pending_calls(PyThreadState *tstate)
if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) {
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. */
signal_pending_calls(tstate, interp);
return -1;
@@ -956,7 +968,7 @@ make_pending_calls(PyThreadState *tstate)
}
}
- pending->handling_thread = NULL;
+ clear_pending_handling_thread(pending);
return 0;
}