diff options
author | Sam Gross <colesbury@gmail.com> | 2024-07-26 17:06:07 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-26 17:06:07 (GMT) |
commit | c557ae97d6bd9d04164a19b4fe136610e54dbdd8 (patch) | |
tree | 918333ecf6b8ef6758c1a6b1c73c00a0e86a045b /Python/ceval_gil.c | |
parent | 64857d849f3079a73367525ce93fd7a463b83908 (diff) | |
download | cpython-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.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; } |