@@ -3199,53 +3199,46 @@ array_iter(arrayobject *ao)
31993199        return  NULL ;
32003200
32013201    it -> ao  =  (arrayobject * )Py_NewRef (ao );
3202-     it -> index  =  0 ;
3202+     it -> index  =  0 ;   // -1 indicates exhausted 
32033203    it -> getitem  =  ao -> ob_descr -> getitem ;
32043204    PyObject_GC_Track (it );
32053205    return  (PyObject  * )it ;
32063206}
32073207
32083208static  PyObject  * 
3209- arrayiter_next_lock_held (arrayiterobject  * it )
3209+ arrayiter_next (arrayiterobject  * it )
32103210{
3211-     _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (it );
3212-     arrayobject  * ao ;
3213- 
3211+     Py_ssize_t  index  =  FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> index );
3212+     if  (index  <  0 ) {
3213+         return  NULL ;
3214+     }
3215+     PyObject  * ret ;
32143216#ifndef  NDEBUG 
32153217    array_state  * state  =  find_array_state_by_type (Py_TYPE (it ));
32163218    assert (PyObject_TypeCheck (it , state -> ArrayIterType ));
3219+     assert (array_Check (it -> ao , state ));
32173220#endif 
3218-     ao  =  it -> ao ;
3219-     if  (ao  ==  NULL ) {
3220-         return  NULL ;
3221+ 
3222+     Py_BEGIN_CRITICAL_SECTION (it -> ao );
3223+     if  (index  <  Py_SIZE (it -> ao )) {
3224+         ret  =  (* it -> getitem )(it -> ao , index );
32213225    }
3222-     PyObject  * ret  =  NULL ;
3223-     Py_BEGIN_CRITICAL_SECTION (ao );
3224- #ifndef  NDEBUG 
3225-     assert (array_Check (ao , state ));
3226- #endif 
3227-     if  (it -> index  <  Py_SIZE (ao )) {
3228-         ret  =  (* it -> getitem )(ao , it -> index ++ );
3226+     else  {
3227+         ret  =  NULL ;
32293228    }
32303229    Py_END_CRITICAL_SECTION ();
3230+ 
32313231    if  (ret  !=  NULL ) {
3232-         return  ret ;
3232+         FT_ATOMIC_STORE_SSIZE_RELAXED (it -> index , index  +  1 );
3233+     }
3234+     else  {
3235+         FT_ATOMIC_STORE_SSIZE_RELAXED (it -> index , -1 );
3236+ #ifndef  Py_GIL_DISABLED 
3237+         arrayobject  * ao  =  it -> ao ;
3238+         it -> ao  =  NULL ;
3239+         Py_DECREF (ao );
3240+ #endif 
32333241    }
3234-     it -> ao  =  NULL ;
3235-     Py_DECREF (ao );
3236-     return  NULL ;
3237- }
3238- 
3239- static  PyObject  * 
3240- arrayiter_next (arrayiterobject  * it )
3241- {
3242-     PyObject  * ret ;
3243-     assert (it  !=  NULL );
3244- 
3245-     Py_BEGIN_CRITICAL_SECTION (it );
3246-     ret  =  arrayiter_next_lock_held (it );
3247-     Py_END_CRITICAL_SECTION ();
3248- 
32493242    return  ret ;
32503243}
32513244
@@ -3269,7 +3262,6 @@ arrayiter_traverse(arrayiterobject *it, visitproc visit, void *arg)
32693262}
32703263
32713264/*[clinic input] 
3272- @critical_section 
32733265array.arrayiterator.__reduce__ 
32743266
32753267    cls: defining_class 
@@ -3280,19 +3272,27 @@ Return state information for pickling.
32803272
32813273static  PyObject  * 
32823274array_arrayiterator___reduce___impl (arrayiterobject  * self , PyTypeObject  * cls )
3283- /*[clinic end generated code: output=4b032417a2c8f5e6 input=61ad213fe49ae0f7 ]*/ 
3275+ /*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e ]*/ 
32843276{
32853277    array_state  * state  =  get_array_state_by_class (cls );
32863278    assert (state  !=  NULL );
32873279    PyObject  * func  =  _PyEval_GetBuiltin (state -> str_iter );
3288-     if  (self -> ao  ==  NULL ) {
3289-         return  Py_BuildValue ("N(())" , func );
3280+     PyObject  * ret  =  NULL ;
3281+     Py_ssize_t  index  =  FT_ATOMIC_LOAD_SSIZE_RELAXED (self -> index );
3282+     if  (index  >= 0 ) {
3283+         Py_BEGIN_CRITICAL_SECTION (self -> ao );
3284+         if  (index  <= Py_SIZE (self -> ao )) {
3285+             ret  =  Py_BuildValue ("N(O)n" , func , self -> ao , index );
3286+         }
3287+         Py_END_CRITICAL_SECTION ();
3288+     }
3289+     if  (ret  ==  NULL ) {
3290+         ret  =  Py_BuildValue ("N(())" , func );
32903291    }
3291-     return  Py_BuildValue ( "N(O)n" ,  func ,  self -> ao ,  self -> index ) ;
3292+     return  ret ;
32923293}
32933294
32943295/*[clinic input] 
3295- @critical_section 
32963296array.arrayiterator.__setstate__ 
32973297
32983298    state: object 
@@ -3302,24 +3302,26 @@ Set state information for unpickling.
33023302[clinic start generated code]*/ 
33033303
33043304static  PyObject  * 
3305- array_arrayiterator___setstate___impl (arrayiterobject  * self , PyObject  * state )
3306- /*[clinic end generated code: output=d7837ae4ac1fd8b9  input=8d8dc7ce40b9c1f7 ]*/ 
3305+ array_arrayiterator___setstate__ (arrayiterobject  * self , PyObject  * state )
3306+ /*[clinic end generated code: output=397da9904e443cbe  input=f47d5ceda19e787b ]*/ 
33073307{
33083308    Py_ssize_t  index  =  PyLong_AsSsize_t (state );
33093309    if  (index  ==  -1  &&  PyErr_Occurred ()) {
33103310        return  NULL ;
33113311    }
3312-     arrayobject  * ao  =  self -> ao ;
3313-     if  (ao  !=  NULL ) {
3314-         Py_BEGIN_CRITICAL_SECTION (ao );
3315-         if  (index  <  0 ) {
3316-             index  =  0 ;
3312+     if  (FT_ATOMIC_LOAD_SSIZE_RELAXED (self -> index ) >= 0 ) {
3313+         Py_BEGIN_CRITICAL_SECTION (self -> ao );
3314+         if  (index  <  -1 ) {
3315+             index  =  -1 ;
33173316        }
3318-         else  if  (index  >  Py_SIZE (ao )) {
3319-             index  =  Py_SIZE (ao ); /* iterator exhausted */ 
3317+         else  {
3318+             Py_ssize_t  size  =  Py_SIZE (self -> ao );
3319+             if  (index  >  size ) {
3320+                 index  =  size ; /* iterator at end */ 
3321+             }
33203322        }
3323+         FT_ATOMIC_STORE_SSIZE_RELAXED (self -> index , index );
33213324        Py_END_CRITICAL_SECTION ();
3322-         self -> index  =  index ;
33233325    }
33243326    Py_RETURN_NONE ;
33253327}
0 commit comments