@@ -624,6 +624,34 @@ PyEval_RestoreThread(PyThreadState *tstate)
624624}
625625
626626
627+ void
628+ _PyEval_SignalReceived (void )
629+ {
630+ _Py_set_eval_breaker_bit (_PyRuntime .main_tstate , _PY_SIGNALS_PENDING_BIT );
631+ }
632+
633+
634+ #ifndef Py_GIL_DISABLED
635+ static void
636+ signal_active_thread (PyInterpreterState * interp , uintptr_t bit )
637+ {
638+ struct _gil_runtime_state * gil = interp -> ceval .gil ;
639+
640+ // If a thread from the targeted interpreter is holding the GIL, signal
641+ // that thread. Otherwise, the next thread to run from the targeted
642+ // interpreter will have its bit set as part of taking the GIL.
643+ MUTEX_LOCK (gil -> mutex );
644+ if (_Py_atomic_load_int_relaxed (& gil -> locked )) {
645+ PyThreadState * holder = (PyThreadState * )_Py_atomic_load_ptr_relaxed (& gil -> last_holder );
646+ if (holder -> interp == interp ) {
647+ _Py_set_eval_breaker_bit (holder , bit );
648+ }
649+ }
650+ MUTEX_UNLOCK (gil -> mutex );
651+ }
652+ #endif
653+
654+
627655/* Mechanism whereby asynchronously executing callbacks (e.g. UNIX
628656 signal handlers or Mac I/O completion routines) can schedule calls
629657 to a function to be called synchronously.
@@ -646,13 +674,6 @@ PyEval_RestoreThread(PyThreadState *tstate)
646674 threadstate.
647675*/
648676
649- void
650- _PyEval_SignalReceived (void )
651- {
652- _Py_set_eval_breaker_bit (_PyRuntime .main_tstate , _PY_SIGNALS_PENDING_BIT );
653- }
654-
655-
656677/* Push one item onto the queue while holding the lock. */
657678static int
658679_push_pending_call (struct _pending_calls * pending ,
@@ -749,27 +770,6 @@ _pop_pending_call(struct _pending_calls *pending,
749770 }
750771}
751772
752-
753- #ifndef Py_GIL_DISABLED
754- static void
755- signal_active_thread (PyInterpreterState * interp , uintptr_t bit )
756- {
757- struct _gil_runtime_state * gil = interp -> ceval .gil ;
758-
759- // If a thread from the targeted interpreter is holding the GIL, signal
760- // that thread. Otherwise, the next thread to run from the targeted
761- // interpreter will have its bit set as part of taking the GIL.
762- MUTEX_LOCK (gil -> mutex );
763- if (_Py_atomic_load_int_relaxed (& gil -> locked )) {
764- PyThreadState * holder = (PyThreadState * )_Py_atomic_load_ptr_relaxed (& gil -> last_holder );
765- if (holder -> interp == interp ) {
766- _Py_set_eval_breaker_bit (holder , bit );
767- }
768- }
769- MUTEX_UNLOCK (gil -> mutex );
770- }
771- #endif
772-
773773/* This implementation is thread-safe. It allows
774774 scheduling to be made from any thread, and even from an executing
775775 callback.
@@ -941,6 +941,7 @@ make_pending_calls(PyThreadState *tstate)
941941 return 0 ;
942942}
943943
944+
944945void
945946_Py_set_eval_breaker_bit_all (PyInterpreterState * interp , uintptr_t bit )
946947{
@@ -976,6 +977,7 @@ _Py_FinishPendingCalls(PyThreadState *tstate)
976977 _Py_IsMainThread () && _Py_IsMainInterpreter (tstate -> interp )
977978 ? & _PyRuntime .ceval .pending_mainthread
978979 : NULL ;
980+
979981 /* make_pending_calls() may return early without making all pending
980982 calls, so we keep trying until we're actually done. */
981983 int32_t npending = INT32_MAX ;
0 commit comments