8000 GH-118095: Make sure that progress is made if there are pending calls… · python/cpython@39981fd · GitHub
[go: up one dir, main page]

Skip to content

Commit 39981fd

Browse files
authored
GH-118095: Make sure that progress is made if there are pending calls being handled. (GH-118484)
1 parent 8a50544 commit 39981fd

File tree

2 files changed

+11
-12
lines changed

2 files changed

+11
-12
lines changed

Include/internal/pycore_ceval_state.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct _pending_call {
4141
#define MAXPENDINGCALLSLOOP_MAIN 0
4242

4343
struct _pending_calls {
44-
int busy;
44+
PyThreadState *handling_thread;
4545
PyMutex mutex;
4646
/* Request for running pending calls. */
4747
int32_t npending;

Python/ceval_gil.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -877,21 +877,20 @@ make_pending_calls(PyThreadState *tstate)
877877
/* Only one thread (per interpreter) may run the pending calls
878878
at once. In the same way, we don't do recursive pending calls. */
879879
PyMutex_Lock(&pending->mutex);
880-
if (pending->busy) {
880+
if (pending->handling_thread != NULL) {
881881
/* A pending call was added after another thread was already
882882
handling the pending calls (and had already "unsignaled").
883883
Once that thread is done, it may have taken care of all the
884884
pending calls, or there might be some still waiting.
885-
Regardless, this interpreter's pending calls will stay
886-
"signaled" until that first thread has finished. At that
887-
point the next thread to trip the eval breaker will take
888-
care of any remaining pending calls. Until then, though,
889-
all the interpreter's threads will be tripping the eval
890-
breaker every time it's checked. */
885+
To avoid all threads constantly stopping on the eval breaker,
886+
we clear the bit for this thread and make sure it is set
887+
for the thread currently handling the pending call. */
888+
_Py_set_eval_breaker_bit(pending->handling_thread, _PY_CALLS_TO_DO_BIT);
889+
_Py_unset_eval_breaker_bit(tstate, _PY_CALLS_TO_DO_BIT);
891890
PyMutex_Unlock(&pending->mutex);
892891
return 0;
893892
}
894-
pending->busy = 1;
893+
pending->handling_thread = tstate;
895894
PyMutex_Unlock(&pending->mutex);
896895

897896
/* unsignal before starting to call callbacks, so that any callback
@@ -900,7 +899,7 @@ make_pending_calls(PyThreadState *tstate)
900899

901900
int32_t npending;
902901
if (_make_pending_calls(pending, &npending) != 0) {
903-
pending->busy = 0;
902+
pending->handling_thread = NULL;
904903
/* There might not be more calls to make, but we play it safe. */
905904
signal_pending_calls(tstate, interp);
906905
return -1;
@@ -912,7 +911,7 @@ make_pending_calls(PyThreadState *tstate)
912911

913912
if (_Py_IsMainThread() && _Py_IsMainInterpreter(interp)) {
914913
if (_make_pending_calls(pending_main, &npending) != 0) {
915-
pending->busy = 0;
914+
pending->handling_thread = NULL;
916915
/* There might not be more calls to make, but we play it safe. */
917916
signal_pending_calls(tstate, interp);
918917
return -1;
@@ -923,7 +922,7 @@ make_pending_calls(PyThreadState *tstate)
923922
}
924923
}
925924

926-
pending->busy = 0;
925+
pending->handling_thread = NULL;
927926
return 0;
928927
}
929928

0 commit comments

Comments
 (0)
0