|
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,12 +949,11 @@ static PyObject * |
942 | 949 | ga_iternext(PyObject *op) |
943 | 950 | { |
944 | 951 | gaiterobject *gi = (gaiterobject*)op; |
945 | | -#ifdef Py_GIL_DISABLED |
946 | | - PyObject *obj = _Py_atomic_exchange_ptr(&gi->obj, NULL); |
947 | | -#else |
948 | | - PyObject* obj = gi->obj; |
| 952 | + PyObject *obj; |
| 953 | + Py_BEGIN_CRITICAL_SECTION(gi); |
| 954 | + obj = gi->obj; |
949 | 955 | gi->obj = NULL; |
950 | | -#endif |
| 956 | + Py_END_CRITICAL_SECTION(); |
951 | 957 | if (obj == NULL) { |
952 | 958 | PyErr_SetNone(PyExc_StopIteration); |
953 | 959 | return NULL; |
@@ -997,10 +1003,19 @@ ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) |
997 | 1003 | * call must be before access of iterator pointers. |
998 | 1004 | * see issue #101765 */ |
999 | 1005 |
|
1000 | | - if (gi->obj) |
1001 | | - return Py_BuildValue("N(O)", iter, gi->obj); |
1002 | | - 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 { |
1003 | 1017 | return Py_BuildValue("N(())", iter); |
| 1018 | + } |
1004 | 1019 | } |
1005 | 1020 |
|
1006 | 1021 | static PyMethodDef ga_iter_methods[] = { |
|
0 commit comments