summaryrefslogtreecommitdiffstats
path: root/Modules/itertoolsmodule.c
diff options
context:
space:
mode:
authorHongWeipeng <961365124@qq.com>2019-08-29 03:39:25 (GMT)
committerRaymond Hettinger <rhettinger@users.noreply.github.com>2019-08-29 03:39:25 (GMT)
commitfa220ec7633e9674baccc28dde987f29d7f65141 (patch)
tree065b6b1b6cadd563ba6e357217318404b6cedc43 /Modules/itertoolsmodule.c
parent13f37f2ba8b1fa39f312dca920e847d9c0313c77 (diff)
downloadcpython-fa220ec7633e9674baccc28dde987f29d7f65141.zip
cpython-fa220ec7633e9674baccc28dde987f29d7f65141.tar.gz
cpython-fa220ec7633e9674baccc28dde987f29d7f65141.tar.bz2
Raise a RuntimeError when tee iterator is consumed from different threads (GH-15567)
Diffstat (limited to 'Modules/itertoolsmodule.c')
-rw-r--r--Modules/itertoolsmodule.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index 781d0cc..101addc 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -452,6 +452,7 @@ typedef struct {
teedataobject *dataobj;
int index; /* 0 <= index <= LINKCELLS */
PyObject *weakreflist;
+ unsigned long thread_id;
} teeobject;
static PyTypeObject teedataobject_type;
@@ -680,6 +681,11 @@ tee_next(teeobject *to)
{
PyObject *value, *link;
+ if (to->thread_id != PyThread_get_thread_ident()) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "tee() iterator can not be consumed from different threads.");
+ return NULL;
+ }
if (to->index >= LINKCELLS) {
link = teedataobject_jumplink(to->dataobj);
if (link == NULL)
@@ -713,6 +719,7 @@ tee_copy(teeobject *to, PyObject *Py_UNUSED(ignored))
newto->dataobj = to->dataobj;
newto->index = to->index;
newto->weakreflist = NULL;
+ newto->thread_id = to->thread_id;
PyObject_GC_Track(newto);
return (PyObject *)newto;
}
@@ -745,6 +752,7 @@ tee_fromiterable(PyObject *iterable)
to->index = 0;
to->weakreflist = NULL;
+ to->thread_id = PyThread_get_thread_ident();
PyObject_GC_Track(to);
done:
Py_XDECREF(it);