|
2 | 2 |
|
3 | 3 | #include "Python.h" |
4 | 4 | #include "pycore_ceval.h" // _PyEval_GetBuiltin() |
| 5 | +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION() |
5 | 6 | #include "pycore_modsupport.h" // _PyArg_NoKeywords() |
6 | 7 | #include "pycore_object.h" |
7 | 8 | #include "pycore_typevarobject.h" // _Py_typing_type_repr |
@@ -578,19 +579,24 @@ PyDoc_STRVAR(genericalias__doc__, |
578 | 579 | "For example, for t = list[int], t.__origin__ is list and t.__args__\n" |
579 | 580 | "is (int,)."); |
580 | 581 |
|
| 582 | +static PyObject * |
| 583 | +ga_parameters_lock_held(PyObject *self); |
| 584 | + |
581 | 585 | static PyObject * |
582 | 586 | ga_getitem(PyObject *self, PyObject *item) |
583 | 587 | { |
584 | 588 | gaobject *alias = (gaobject *)self; |
585 | 589 | // Populate __parameters__ if needed. |
586 | | - if (alias->parameters == NULL) { |
587 | | - alias->parameters = _Py_make_parameters(alias->args); |
588 | | - if (alias->parameters == NULL) { |
589 | | - return NULL; |
590 | | - } |
| 590 | + PyObject *parameters; |
| 591 | + Py_BEGIN_CRITICAL_SECTION(self); |
| 592 | + parameters = ga_parameters_lock_held(self); |
| 593 | + Py_END_CRITICAL_SECTION(); |
| 594 | + if (parameters == NULL) { |
| 595 | + return NULL; |
591 | 596 | } |
592 | 597 |
|
593 | | - PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item); |
| 598 | + PyObject *newargs = _Py_subs_parameters(self, alias->args, parameters, item); |
| 599 | + Py_DECREF(parameters); |
594 | 600 | if (newargs == NULL) { |
595 | 601 | return NULL; |
596 | 602 | } |
@@ -846,6 +852,7 @@ static PyMemberDef ga_members[] = { |
846 | 852 | static PyObject * |
847 | 853 | ga_parameters_lock_held(PyObject *self) |
848 | 854 | { |
| 855 | + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self); |
849 | 856 | gaobject *alias = (gaobject *)self; |
850 | 857 | if (alias->parameters == NULL) { |
851 | 858 | alias->parameters = _Py_make_parameters(alias->args); |
@@ -942,17 +949,22 @@ static PyObject * |
942 | 949 | ga_iternext(PyObject *op) |
943 | 950 | { |
944 | 951 | gaiterobject *gi = (gaiterobject*)op; |
945 | | - if (gi->obj == NULL) { |
| 952 | + PyObject *obj; |
| 953 | + Py_BEGIN_CRITICAL_SECTION(gi); |
| 954 | + obj = gi->obj; |
| 955 | + gi->obj = NULL; |
| 956 | + Py_END_CRITICAL_SECTION(); |
| 957 | + if (obj == NULL) { |
946 | 958 | PyErr_SetNone(PyExc_StopIteration); |
947 | 959 | return NULL; |
948 | 960 | } |
949 | | - gaobject *alias = (gaobject *)gi->obj; |
| 961 | + gaobject *alias = (gaobject *)obj; |
950 | 962 | PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args); |
| 963 | + Py_DECREF(obj); |
951 | 964 | if (starred_alias == NULL) { |
952 | 965 | return NULL; |
953 | 966 | } |
954 | 967 | ((gaobject *)starred_alias)->starred = true; |
955 | | - Py_SETREF(gi->obj, NULL); |
956 | 968 | return starred_alias; |
957 | 969 | } |
958 | 970 |
|
@@ -991,10 +1003,19 @@ ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) |
991 | 1003 | * call must be before access of iterator pointers. |
992 | 1004 | * see issue #101765 */ |
993 | 1005 |
|
994 | | - if (gi->obj) |
995 | | - return Py_BuildValue("N(O)", iter, gi->obj); |
996 | | - else |
| 1006 | + PyObject *obj; |
| 1007 | + Py_BEGIN_CRITICAL_SECTION(gi); |
| 1008 | + obj = Py_XNewRef(gi->obj); |
| 1009 | + Py_END_CRITICAL_SECTION(); |
| 1010 | + |
| 1011 | + if (obj) { |
| 1012 | + PyObject *result = Py_BuildValue("N(O)", iter, obj); |
| 1013 | + Py_DECREF(obj); |
| 1014 | + return result; |
| 1015 | + } |
| 1016 | + else { |
997 | 1017 | return Py_BuildValue("N(())", iter); |
| 1018 | + } |
998 | 1019 | } |
999 | 1020 |
|
1000 | 1021 | static PyMethodDef ga_iter_methods[] = { |
|
0 commit comments