diff options
| author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2024-07-26 17:30:08 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-26 17:30:08 (GMT) |
| commit | 9d5dde50068e1d3778444fb5e302b4567ebfc232 (patch) | |
| tree | 4be61ad7ca5f2c6819d6a985a1afb5faed3fbf1b /Python | |
| parent | 816a1572e56f7051b861c0f28c91da676e0e4ef8 (diff) | |
| download | cpython-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.c | 18 |
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; } |
