[3.13] gh-118297: Make Sure All Pending Calls Run in _Py_FinishPendingCalls() (gh-121806)

(cherry picked from commit 985dd8e17b, AKA gh-118298)

Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-07-15 21:09:40 +02:00 committed by GitHub
parent 308857b82a
commit ff65d1e054
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -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