Skip to content

Commit 2f6139f

Browse files
committed
Add _PyEval_RaiseAsyncExc; call it from PyErr_CheckSignals
1 parent da5c286 commit 2f6139f

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

Include/internal/pycore_ceval.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,9 @@ PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func);
286286
and asynchronous exception */
287287
PyAPI_FUNC(int) _Py_HandlePending(PyThreadState *tstate);
288288

289+
/* Raise exception set by PyThreadState_SetAsyncExc, if any */
290+
PyAPI_FUNC(int) _PyEval_RaiseAsyncExc(PyThreadState *tstate);
291+
289292
extern PyObject * _PyEval_GetFrameLocals(void);
290293

291294
typedef PyObject *(*conversion_func)(PyObject *);

Modules/signalmodule.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,20 +1781,28 @@ PyErr_CheckSignals(void)
17811781
Python code to ensure signals are handled. Checking for the GC here
17821782
allows long running native code to clean cycles created using the C-API
17831783
even if it doesn't run the evaluation loop */
1784-
if (_Py_eval_breaker_bit_is_set(tstate, _PY_GC_SCHEDULED_BIT)) {
1784+
uintptr_t breaker = _Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker);
1785+
if (breaker & _PY_GC_SCHEDULED_BIT) {
17851786
_Py_unset_eval_breaker_bit(tstate, _PY_GC_SCHEDULED_BIT);
17861787
_Py_RunGC(tstate);
17871788
}
1789+
if (breaker & _PY_ASYNC_EXCEPTION_BIT) {
1790+
if (_PyEval_RaiseAsyncExc(tstate) < 0) {
1791+
return -1;
1792+
}
1793+
}
17881794

17891795
#if defined(Py_REMOTE_DEBUG) && defined(Py_SUPPORTS_REMOTE_DEBUG)
17901796
_PyRunRemoteDebugger(tstate);
17911797
#endif
17921798

1793-
if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
1794-
return 0;
1799+
if (_Py_ThreadCanHandleSignals(tstate->interp)) {
1800+
if (_PyErr_CheckSignalsTstate(tstate) < 0) {
1801+
return -1;
1802+
}
17951803
}
17961804

1797-
return _PyErr_CheckSignalsTstate(tstate);
1805+
return 0;
17981806
}
17991807

18001808

Python/ceval_gil.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1423,11 +1423,7 @@ _Py_HandlePending(PyThreadState *tstate)
14231423

14241424
/* Check for asynchronous exception. */
14251425
if ((breaker & _PY_ASYNC_EXCEPTION_BIT) != 0) {
1426-
_Py_unset_eval_breaker_bit(tstate, _PY_ASYNC_EXCEPTION_BIT);
1427-
PyObject *exc = _Py_atomic_exchange_ptr(&tstate->async_exc, NULL);
1428-
if (exc != NULL) {
1429-
_PyErr_SetNone(tstate, exc);
1430-
Py_DECREF(exc);
1426+
if (_PyEval_RaiseAsyncExc(tstate) < 0) {
14311427
return -1;
14321428
}
14331429
}
@@ -1438,3 +1434,16 @@ _Py_HandlePending(PyThreadState *tstate)
14381434

14391435
return 0;
14401436
}
1437+
1438+
int
1439+
_PyEval_RaiseAsyncExc(PyThreadState *tstate)
1440+
{
1441+
_Py_unset_eval_breaker_bit(tstate, _PY_ASYNC_EXCEPTION_BIT);
1442+
PyObject *exc = _Py_atomic_exchange_ptr(&tstate->async_exc, NULL);
1443+
if (exc != NULL) {
1444+
_PyErr_SetNone(tstate, exc);
1445+
Py_DECREF(exc);
1446+
return -1;
1447+
}
1448+
return 0;
1449+
}

0 commit comments

Comments
 (0)