summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-07-26 17:30:08 (GMT)
committerGitHub <noreply@github.com>2024-07-26 17:30:08 (GMT)
commit9d5dde50068e1d3778444fb5e302b4567ebfc232 (patch)
tree4be61ad7ca5f2c6819d6a985a1afb5faed3fbf1b /Python
parent816a1572e56f7051b861c0f28c91da676e0e4ef8 (diff)
downloadcpython-9d5dde50068e1d3778444fb5e302b4567ebfc232.zip
cpython-9d5dde50068e1d3778444fb5e302b4567ebfc232.tar.gz
cpython-9d5dde50068e1d3778444fb5e302b4567ebfc232.tar.bz2
[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 c557ae97d6bd9d04164a19b4fe136610e54dbdd8) Co-authored-by: Sam Gross <colesbury@gmail.com>
Diffstat (limited to 'Python')
-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;
}