summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
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