@@ -2856,31 +2856,44 @@ static PyObject *
28562856bytearrayiter_next (PyObject * self )
28572857{
28582858 bytesiterobject * it = _bytesiterobject_CAST (self );
2859- PyByteArrayObject * seq ;
2859+ int val ;
28602860
28612861 assert (it != NULL );
2862- seq = it -> it_seq ;
2863- if (seq == NULL )
2862+ Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED ( it -> it_index ) ;
2863+ if (index < 0 ) {
28642864 return NULL ;
2865+ }
2866+ PyByteArrayObject * seq = it -> it_seq ;
28652867 assert (PyByteArray_Check (seq ));
28662868
2867- if (it -> it_index < PyByteArray_GET_SIZE (seq )) {
2868- return _PyLong_FromUnsignedChar (
2869- (unsigned char )PyByteArray_AS_STRING (seq )[it -> it_index ++ ]);
2869+ Py_BEGIN_CRITICAL_SECTION (seq );
2870+ if (index < Py_SIZE (seq )) {
2871+ val = (unsigned char )PyByteArray_AS_STRING (seq )[index ];
2872+ }
2873+ else {
2874+ val = -1 ;
28702875 }
2876+ Py_END_CRITICAL_SECTION ();
28712877
2872- it -> it_seq = NULL ;
2873- Py_DECREF (seq );
2874- return NULL ;
2878+ if (val == -1 ) {
2879+ FT_ATOMIC_STORE_SSIZE_RELAXED (it -> it_index , -1 );
2880+ #ifndef Py_GIL_DISABLED
2881+ Py_CLEAR (it -> it_seq );
2882+ #endif
2883+ return NULL ;
2884+ }
2885+ FT_ATOMIC_STORE_SSIZE_RELAXED (it -> it_index , index + 1 );
2886+ return _PyLong_FromUnsignedChar ((unsigned char )val );
28752887}
28762888
28772889static PyObject *
28782890bytearrayiter_length_hint (PyObject * self , PyObject * Py_UNUSED (ignored ))
28792891{
28802892 bytesiterobject * it = _bytesiterobject_CAST (self );
28812893 Py_ssize_t len = 0 ;
2882- if (it -> it_seq ) {
2883- len = PyByteArray_GET_SIZE (it -> it_seq ) - it -> it_index ;
2894+ Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> it_index );
2895+ if (index >= 0 ) {
2896+ len = PyByteArray_GET_SIZE (it -> it_seq ) - index ;
28842897 if (len < 0 ) {
28852898 len = 0 ;
28862899 }
@@ -2900,27 +2913,33 @@ bytearrayiter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
29002913 * call must be before access of iterator pointers.
29012914 * see issue #101765 */
29022915 bytesiterobject * it = _bytesiterobject_CAST (self );
2903- if (it -> it_seq != NULL ) {
2904- return Py_BuildValue ("N(O)n" , iter , it -> it_seq , it -> it_index );
2905- } else {
2906- return Py_BuildValue ("N(())" , iter );
2916+ Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> it_index );
2917+ if (index >= 0 ) {
2918+ return Py_BuildValue ("N(O)n" , iter , it -> it_seq , index );
29072919 }
2920+ return Py_BuildValue ("N(())" , iter );
29082921}
29092922
29102923static PyObject *
29112924bytearrayiter_setstate (PyObject * self , PyObject * state )
29122925{
29132926 Py_ssize_t index = PyLong_AsSsize_t (state );
2914- if (index == -1 && PyErr_Occurred ())
2927+ if (index == -1 && PyErr_Occurred ()) {
29152928 return NULL ;
2929+ }
29162930
29172931 bytesiterobject * it = _bytesiterobject_CAST (self );
2918- if (it -> it_seq != NULL ) {
2919- if (index < 0 )
2920- index = 0 ;
2921- else if (index > PyByteArray_GET_SIZE (it -> it_seq ))
2922- index = PyByteArray_GET_SIZE (it -> it_seq ); /* iterator exhausted */
2923- it -> it_index = index ;
2932+ if (FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> it_index ) >= 0 ) {
2933+ if (index < -1 ) {
2934+ index = -1 ;
2935+ }
2936+ else {
2937+ Py_ssize_t size = PyByteArray_GET_SIZE (it -> it_seq );
2938+ if (index > size ) {
2939+ index = size ; /* iterator at end */
2940+ }
2941+ }
2942+ FT_ATOMIC_STORE_SSIZE_RELAXED (it -> it_index , index );
29242943 }
29252944 Py_RETURN_NONE ;
29262945}
@@ -2982,7 +3001,7 @@ bytearray_iter(PyObject *seq)
29823001 it = PyObject_GC_New (bytesiterobject , & PyByteArrayIter_Type );
29833002 if (it == NULL )
29843003 return NULL ;
2985- it -> it_index = 0 ;
3004+ it -> it_index = 0 ; // -1 indicates exhausted
29863005 it -> it_seq = (PyByteArrayObject * )Py_NewRef (seq );
29873006 _PyObject_GC_TRACK (it );
29883007 return (PyObject * )it ;
0 commit comments