summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorChris Jerdonek <chris.jerdonek@gmail.com>2020-05-22 20:33:27 (GMT)
committerGitHub <noreply@github.com>2020-05-22 20:33:27 (GMT)
commit7c30d12bd5359b0f66c4fbc98aa055398bcc8a7e (patch)
tree2719af29b9bd410f1ed7f70b1ab1d3c9357713e0 /Modules
parent909b5714e1303357868bc5e281c1cf508d5d5a17 (diff)
downloadcpython-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.c12
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;
}