@@ -1056,23 +1056,24 @@ setiter_len(PyObject *op, PyObject *Py_UNUSED(ignored))
10561056{
10571057 setiterobject * si = (setiterobject * )op ;
10581058 Py_ssize_t len = 0 ;
1059+
10591060#ifdef Py_GIL_DISABLED
10601061 PySetObject * so = si -> si_set ;
10611062 if (so != NULL ) {
1062- Py_BEGIN_CRITICAL_SECTION (so );
1063- Py_ssize_t pos = FT_ATOMIC_LOAD_SSIZE_RELAXED (si -> si_pos );
1064- if (pos >= 0 &&
1063+ Py_BEGIN_CRITICAL_SECTION2 (op , so );
1064+ if (si -> si_pos >= 0 &&
10651065 si -> si_used == FT_ATOMIC_LOAD_SSIZE_RELAXED (so -> used ))
10661066 {
10671067 len = si -> len ;
10681068 }
1069- Py_END_CRITICAL_SECTION ();
1069+ Py_END_CRITICAL_SECTION2 ();
10701070 }
10711071#else
10721072 if (si -> si_set != NULL && si -> si_used == si -> si_set -> used ) {
10731073 len = si -> len ;
10741074 }
10751075#endif
1076+
10761077 return PyLong_FromSsize_t (len );
10771078}
10781079
@@ -1104,18 +1105,22 @@ static PyMethodDef setiter_methods[] = {
11041105 {NULL , NULL } /* sentinel */
11051106};
11061107
1107- static PyObject * setiter_iternext (PyObject * self )
1108+ static PyObject *
1109+ setiter_iternext (PyObject * self )
11081110{
11091111 setiterobject * si = (setiterobject * )self ;
11101112 PyObject * key = NULL ;
11111113 Py_ssize_t i , mask ;
11121114 setentry * entry ;
11131115 PySetObject * so = si -> si_set ;
1114- int exhausted = 0 ;
1116+ #ifndef Py_GIL_DISABLED
1117+ int decref_so = 0 ;
1118+ #endif
11151119
1116- if (so == NULL )
1120+ if (so == NULL ) {
11171121 return NULL ;
1118- assert (PyAnySet_Check (so ));
1122+ }
1123+ assert (PyAnySet_Check (so ));
11191124
11201125 Py_ssize_t so_used = FT_ATOMIC_LOAD_SSIZE_RELAXED (so -> used );
11211126 Py_ssize_t si_used = FT_ATOMIC_LOAD_SSIZE_RELAXED (si -> si_used );
@@ -1126,61 +1131,54 @@ static PyObject *setiter_iternext(PyObject *self)
11261131 return NULL ;
11271132 }
11281133
1129- Py_BEGIN_CRITICAL_SECTION (so );
11301134#ifdef Py_GIL_DISABLED
1131- /* si_pos may be read outside the lock; keep it atomic in FT builds */
1132- i = FT_ATOMIC_LOAD_SSIZE_RELAXED (si -> si_pos );
1133- if (i < 0 ) {
1134- /* iterator already exhausted */
1135- goto done ;
1136- }
1137- #else
1135+ Py_BEGIN_CRITICAL_SECTION2 (self , so );
11381136 i = si -> si_pos ;
1139- if (i < 0 ) {
1140- /* iterator already exhausted */
1141- exhausted = 1 ;
1142- }
1143- #endif
1144-
1145- if (!exhausted ) {
1146- assert (i >= 0 );
1137+ if (i >= 0 ) {
11471138 entry = so -> table ;
11481139 mask = so -> mask ;
1149- while (i <= mask && (entry [i ].key == NULL || entry [i ].key == dummy )) {
1140+ while (i <= mask &&
1141+ (entry [i ].key == NULL || entry [i ].key == dummy )) {
11501142 i ++ ;
11511143 }
11521144 if (i <= mask ) {
11531145 key = Py_NewRef (entry [i ].key );
1154- #ifdef Py_GIL_DISABLED
1155- FT_ATOMIC_STORE_SSIZE_RELAXED (si -> si_pos , i + 1 );
1156- #else
11571146 si -> si_pos = i + 1 ;
1158- #endif
11591147 si -> len -- ;
11601148 }
11611149 else {
1162- #ifdef Py_GIL_DISABLED
1163- /* free-threaded: keep si_set; just mark exhausted */
1164- FT_ATOMIC_STORE_SSIZE_RELAXED (si -> si_pos , -1 );
1150+ si -> si_pos = -1 ;
11651151 si -> len = 0 ;
1166- #else
1167- si -> si_set = NULL ;
1168- #endif
11691152 }
11701153 }
1171-
1172- #ifdef Py_GIL_DISABLED
1173- done :
1174- #endif
1154+ Py_END_CRITICAL_SECTION2 ();
1155+ return key ;
1156+ #else
1157+ Py_BEGIN_CRITICAL_SECTION (so );
1158+ i = si -> si_pos ;
1159+ entry = so -> table ;
1160+ mask = so -> mask ;
1161+ while (i <= mask &&
1162+ (entry [i ].key == NULL || entry [i ].key == dummy )) {
1163+ i ++ ;
1164+ }
1165+ if (i <= mask ) {
1166+ key = Py_NewRef (entry [i ].key );
1167+ si -> si_pos = i + 1 ;
1168+ si -> len -- ;
1169+ }
1170+ else {
1171+ si -> si_set = NULL ;
1172+ decref_so = 1 ;
1173+ }
11751174 Py_END_CRITICAL_SECTION ();
11761175
1177- if (key == NULL ) {
1178- #ifndef Py_GIL_DISABLED
1176+ if (decref_so ) {
11791177 Py_DECREF (so );
1180- #endif
11811178 return NULL ;
11821179 }
11831180 return key ;
1181+ #endif
11841182}
11851183
11861184PyTypeObject PySetIter_Type = {
0 commit comments