diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2024-07-15 18:44:20 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-15 18:44:20 (GMT) |
commit | 985dd8e17b55ae35fc31546384fc9364f2f59f86 (patch) | |
tree | 7c1b060686805a7011052439c0c79dd47c8f11e3 /Python | |
parent | 6522f0e438a8c56a8f3cce2095b193ea6e3f5016 (diff) | |
download | cpython-985dd8e17b55ae35fc31546384fc9364f2f59f86.zip cpython-985dd8e17b55ae35fc31546384fc9364f2f59f86.tar.gz cpython-985dd8e17b55ae35fc31546384fc9364f2f59f86.tar.bz2 |
gh-118297: Make Sure All Pending Calls Run in _Py_FinishPendingCalls() (gh-118298)
Diffstat (limited to 'Python')
-rw-r--r-- | Python/ceval_gil.c | 34 |
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 |