|
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 |
@@ -588,19 +589,24 @@ PyDoc_STRVAR(genericalias__doc__, |
588 | 589 | "For example, for t = list[int], t.__origin__ is list and t.__args__\n" |
589 | 590 | "is (int,)."); |
590 | 591 |
|
| 592 | +static PyObject * |
| 593 | +ga_parameters_lock_held(PyObject *self); |
| 594 | + |
591 | 595 | static PyObject * |
592 | 596 | ga_getitem(PyObject *self, PyObject *item) |
593 | 597 | { |
594 | 598 | gaobject *alias = (gaobject *)self; |
595 | 599 | // Populate __parameters__ if needed. |
596 | | - if (alias->parameters == NULL) { |
597 | | - alias->parameters = _Py_make_parameters(alias->args); |
598 | | - if (alias->parameters == NULL) { |
599 | | - return NULL; |
600 | | - } |
| 600 | + PyObject *parameters; |
| 601 | + Py_BEGIN_CRITICAL_SECTION(self); |
| 602 | + parameters = ga_parameters_lock_held(self); |
| 603 | + Py_END_CRITICAL_SECTION(); |
| 604 | + if (parameters == NULL) { |
| 605 | + return NULL; |
601 | 606 | } |
602 | 607 |
|
603 | | - PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item); |
| 608 | + PyObject *newargs = _Py_subs_parameters(self, alias->args, parameters, item); |
| 609 | + Py_DECREF(parameters); |
604 | 610 | if (newargs == NULL) { |
605 | 611 | return NULL; |
606 | 612 | } |
@@ -856,6 +862,7 @@ static PyMemberDef ga_members[] = { |
856 | 862 | static PyObject * |
857 | 863 | ga_parameters_lock_held(PyObject *self) |
858 | 864 | { |
| 865 | + _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self); |
859 | 866 | gaobject *alias = (gaobject *)self; |
860 | 867 | if (alias->parameters == NULL) { |
861 | 868 | alias->parameters = _Py_make_parameters(alias->args); |
@@ -952,17 +959,22 @@ static PyObject * |
952 | 959 | ga_iternext(PyObject *op) |
953 | 960 | { |
954 | 961 | gaiterobject *gi = (gaiterobject*)op; |
955 | | - if (gi->obj == NULL) { |
| 962 | + PyObject *obj; |
| 963 | + Py_BEGIN_CRITICAL_SECTION(gi); |
| 964 | + obj = gi->obj; |
| 965 | + gi->obj = NULL; |
| 966 | + Py_END_CRITICAL_SECTION(); |
| 967 | + if (obj == NULL) { |
956 | 968 | PyErr_SetNone(PyExc_StopIteration); |
957 | 969 | return NULL; |
958 | 970 | } |
959 | | - gaobject *alias = (gaobject *)gi->obj; |
| 971 | + gaobject *alias = (gaobject *)obj; |
960 | 972 | PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args); |
| 973 | + Py_DECREF(obj); |
961 | 974 | if (starred_alias == NULL) { |
962 | 975 | return NULL; |
963 | 976 | } |
964 | 977 | ((gaobject *)starred_alias)->starred = true; |
965 | | - Py_SETREF(gi->obj, NULL); |
966 | 978 | return starred_alias; |
967 | 979 | } |
968 | 980 |
|
@@ -1001,10 +1013,19 @@ ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) |
1001 | 1013 | * call must be before access of iterator pointers. |
1002 | 1014 | * see issue #101765 */ |
1003 | 1015 |
|
1004 | | - if (gi->obj) |
1005 | | - return Py_BuildValue("N(O)", iter, gi->obj); |
1006 | | - else |
| 1016 | + PyObject *obj; |
| 1017 | + Py_BEGIN_CRITICAL_SECTION(gi); |
| 1018 | + obj = Py_XNewRef(gi->obj); |
| 1019 | + Py_END_CRITICAL_SECTION(); |
| 1020 | + |
| 1021 | + if (obj) { |
| 1022 | + PyObject *result = Py_BuildValue("N(O)", iter, obj); |
| 1023 | + Py_DECREF(obj); |
| 1024 | + return result; |
| 1025 | + } |
| 1026 | + else { |
1007 | 1027 | return Py_BuildValue("N(())", iter); |
| 1028 | + } |
1008 | 1029 | } |
1009 | 1030 |
|
1010 | 1031 | static PyMethodDef ga_iter_methods[] = { |
|
0 commit comments