diff options
author | Chris Jerdonek <chris.jerdonek@gmail.com> | 2020-05-22 20:33:27 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-22 20:33:27 (GMT) |
commit | 7c30d12bd5359b0f66c4fbc98aa055398bcc8a7e (patch) | |
tree | 2719af29b9bd410f1ed7f70b1ab1d3c9357713e0 /Modules | |
parent | 909b5714e1303357868bc5e281c1cf508d5d5a17 (diff) | |
download | cpython-7c30d12bd5359b0f66c4fbc98aa055398bcc8a7e.zip cpython-7c30d12bd5359b0f66c4fbc98aa055398bcc8a7e.tar.gz cpython-7c30d12bd5359b0f66c4fbc98aa055398bcc8a7e.tar.bz2 |
bpo-40696: Fix a hang that can arise after gen.throw() (GH-20287)
This updates _PyErr_ChainStackItem() to use _PyErr_SetObject()
instead of _PyErr_ChainExceptions(). This prevents a hang in
certain circumstances because _PyErr_SetObject() performs checks
to prevent cycles in the exception context chain while
_PyErr_ChainExceptions() doesn't.
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_asynciomodule.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index 1b6a579..0608c40 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -612,19 +612,20 @@ create_cancelled_error(PyObject *msg) } static void -set_cancelled_error(PyObject *msg) +future_set_cancelled_error(FutureObj *fut) { - PyObject *exc = create_cancelled_error(msg); + PyObject *exc = create_cancelled_error(fut->fut_cancel_msg); PyErr_SetObject(asyncio_CancelledError, exc); Py_DECREF(exc); + + _PyErr_ChainStackItem(&fut->fut_cancelled_exc_state); } static int future_get_result(FutureObj *fut, PyObject **result) { if (fut->fut_state == STATE_CANCELLED) { - set_cancelled_error(fut->fut_cancel_msg); - _PyErr_ChainStackItem(&fut->fut_cancelled_exc_state); + future_set_cancelled_error(fut); return -1; } @@ -866,8 +867,7 @@ _asyncio_Future_exception_impl(FutureObj *self) } if (self->fut_state == STATE_CANCELLED) { - set_cancelled_error(self->fut_cancel_msg); - _PyErr_ChainStackItem(&self->fut_cancelled_exc_state); + future_set_cancelled_error(self); return NULL; } |