summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-07-15 19:09:40 (GMT)
committerGitHub <noreply@github.com>2024-07-15 19:09:40 (GMT)
commitff65d1e0547a83a39f050b6ee86ebc22479f1e09 (patch)
tree143fcf17ac1a36b732b6d4de0a25bb443d1c07c8 /Python
parent308857b82ad0728b3be6435b056923ecdf82fce3 (diff)
downloadcpython-ff65d1e0547a83a39f050b6ee86ebc22479f1e09.zip
cpython-ff65d1e0547a83a39f050b6ee86ebc22479f1e09.tar.gz
cpython-ff65d1e0547a83a39f050b6ee86ebc22479f1e09.tar.bz2
[3.13] gh-118297: Make Sure All Pending Calls Run in _Py_FinishPendingCalls() (gh-121806)
(cherry picked from commit 985dd8e17b55ae35fc31546384fc9364f2f59f86, AKA gh-118298) Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
Diffstat (limited to 'Python')
-rw-r--r--Python/ceval_gil.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c
index 5617504..dc3baf7 100644
--- a/Python/ceval_gil.c
+++ b/Python/ceval_gil.c
@@ -991,12 +991,34 @@ _Py_FinishPendingCalls(PyThreadState *tstate)
assert(PyGILState_Check());
assert(_PyThreadState_CheckConsistency(tstate));
- if (make_pending_calls(tstate) < 0) {
- PyObject *exc = _PyErr_GetRaisedException(tstate);
- PyErr_BadInternalCall();
- _PyErr_ChainExceptions1(exc);
- _PyErr_Print(tstate);
- }
+ struct _pending_calls *pending = &tstate->interp->ceval.pending;
+ struct _pending_calls *pending_main =
+ _Py_IsMainThread() && _Py_IsMainInterpreter(tstate->interp)
+ ? &_PyRuntime.ceval.pending_mainthread
+ : NULL;
+ /* make_pending_calls() may return early without making all pending
+ calls, so we keep trying until we're actually done. */
+ int32_t npending;
+#ifndef NDEBUG
+ int32_t npending_prev = INT32_MAX;
+#endif
+ do {
+ if (make_pending_calls(tstate) < 0) {
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
+ PyErr_BadInternalCall();
+ _PyErr_ChainExceptions1(exc);
+ _PyErr_Print(tstate);
+ }
+
+ npending = _Py_atomic_load_int32_relaxed(&pending->npending);
+ if (pending_main != NULL) {
+ npending += _Py_atomic_load_int32_relaxed(&pending_main->npending);
+ }
+#ifndef NDEBUG
+ assert(npending_prev > npending);
+ npending_prev = npending;
+#endif
+ } while (npending > 0);
}
int