@@ -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