@@ -177,23 +177,34 @@ enum_next_long(enumobject *en, PyObject* next_item)
177
177
PyObject * old_index ;
178
178
PyObject * old_item ;
179
179
180
- if (en -> en_longindex == NULL ) {
181
- en -> en_longindex = PyLong_FromSsize_t (PY_SSIZE_T_MAX );
182
- if (en -> en_longindex == NULL ) {
180
+ #ifdef Py_GIL_DISABLED
181
+ // resets en->en_longindex to 0, but we will restore it later
182
+ PyObject * en_longindex = ( PyObject * )_Py_atomic_exchange_ptr (& en -> en_longindex , NULL );
183
+ #else
184
+ PyObject * en_longindex = en -> en_longindex ;
185
+ #endif
186
+ if (en_longindex == NULL ) {
187
+ en_longindex = PyLong_FromSsize_t (PY_SSIZE_T_MAX );
188
+ if (en_longindex == NULL ) {
183
189
Py_DECREF (next_item );
184
190
return NULL ;
185
191
}
186
192
}
187
- next_index = en -> en_longindex ;
193
+ next_index = en_longindex ;
188
194
assert (next_index != NULL );
189
195
stepped_up = PyNumber_Add (next_index , en -> one );
190
196
if (stepped_up == NULL ) {
191
197
Py_DECREF (next_item );
192
198
return NULL ;
193
199
}
200
+ #ifdef Py_GIL_DISABLED
201
+ PyObject * en_longindex_old = ( PyObject * )_Py_atomic_exchange_ptr (& en -> en_longindex , stepped_up );
202
+ Py_XDECREF (en_longindex_old );
203
+ #else
194
204
en -> en_longindex = stepped_up ;
205
+ #endif
195
206
196
- if (Py_REFCNT (result ) == 1 ) {
207
+ if (_PyObject_IsUniquelyReferenced (result )) {
197
208
Py_INCREF (result );
198
209
old_index = PyTuple_GET_ITEM (result , 0 );
199
210
old_item = PyTuple_GET_ITEM (result , 1 );
@@ -233,17 +244,19 @@ enum_next(enumobject *en)
233
244
if (next_item == NULL )
234
245
return NULL ;
235
246
236
- if (en -> en_index == PY_SSIZE_T_MAX )
247
+ Py_ssize_t en_index = FT_ATOMIC_LOAD_SSIZE_RELAXED (en -> en_index );
248
+ if (en_index == PY_SSIZE_T_MAX )
237
249
return enum_next_long (en , next_item );
238
250
239
- next_index = PyLong_FromSsize_t (en -> en_index );
251
+
252
+ next_index = PyLong_FromSsize_t (en_index );
240
253
if (next_index == NULL ) {
241
254
Py_DECREF (next_item );
242
255
return NULL ;
243
256
}
244
- en -> en_index ++ ;
257
+ FT_ATOMIC_STORE_SSIZE_RELAXED ( en -> en_index , en_index + 1 ) ;
245
258
246
- if (Py_REFCNT (result ) == 1 ) {
259
+ if (_PyObject_IsUniquelyReferenced (result )) {
247
260
Py_INCREF (result );
248
261
old_index = PyTuple_GET_ITEM (result , 0 );
249
262
old_item = PyTuple_GET_ITEM (result , 1 );
@@ -272,10 +285,23 @@ enum_next(enumobject *en)
272
285
static PyObject *
273
286
enum_reduce (enumobject * en , PyObject * Py_UNUSED (ignored ))
274
287
{
275
- if (en -> en_longindex != NULL )
276
- return Py_BuildValue ("O(OO)" , Py_TYPE (en ), en -> en_sit , en -> en_longindex );
277
- else
288
+ #ifdef Py_GIL_DISABLED
289
+ PyObject * en_longindex = ( PyObject * )_Py_atomic_exchange_ptr (& en -> en_longindex , NULL );
290
+ #else
291
+ PyObject * en_longindex = en -> en_longindex ;
292
+ #endif
293
+ if (en_longindex != NULL ) {
294
+ PyObject * value = Py_BuildValue ("O(OO)" , Py_TYPE (en ), en -> en_sit , en_longindex );
295
+ #ifdef Py_GIL_DISABLED
296
+ // restore value of en->en_longindex
297
+ PyObject * en_longindex_old = ( PyObject * )_Py_atomic_exchange_ptr (& en -> en_longindex , en_longindex );
298
+ Py_XDECREF (en_longindex_old );
299
+ #endif
300
+ return value ;
301
+ }
302
+ else {
278
303
return Py_BuildValue ("O(On)" , Py_TYPE (en ), en -> en_sit , en -> en_index );
304
+ }
279
305
}
280
306
281
307
PyDoc_STRVAR (reduce_doc , "Return state information for pickling." );
0 commit comments