@@ -2856,31 +2856,44 @@ static PyObject *
2856
2856
bytearrayiter_next (PyObject * self )
2857
2857
{
2858
2858
bytesiterobject * it = _bytesiterobject_CAST (self );
2859
- PyByteArrayObject * seq ;
2859
+ int val ;
2860
2860
2861
2861
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 ) {
2864
2864
return NULL ;
2865
+ }
2866
+ PyByteArrayObject * seq = it -> it_seq ;
2865
2867
assert (PyByteArray_Check (seq ));
2866
2868
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 ;
2870
2875
}
2876
+ Py_END_CRITICAL_SECTION ();
2871
2877
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 );
2875
2887
}
2876
2888
2877
2889
static PyObject *
2878
2890
bytearrayiter_length_hint (PyObject * self , PyObject * Py_UNUSED (ignored ))
2879
2891
{
2880
2892
bytesiterobject * it = _bytesiterobject_CAST (self );
2881
2893
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 ;
2884
2897
if (len < 0 ) {
2885
2898
len = 0 ;
2886
2899
}
@@ -2900,27 +2913,33 @@ bytearrayiter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
2900
2913
* call must be before access of iterator pointers.
2901
2914
* see issue #101765 */
2902
2915
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 );
2907
2919
}
2920
+ return Py_BuildValue ("N(())" , iter );
2908
2921
}
2909
2922
2910
2923
static PyObject *
2911
2924
bytearrayiter_setstate (PyObject * self , PyObject * state )
2912
2925
{
2913
2926
Py_ssize_t index = PyLong_AsSsize_t (state );
2914
- if (index == -1 && PyErr_Occurred ())
2927
+ if (index == -1 && PyErr_Occurred ()) {
2915
2928
return NULL ;
2929
+ }
2916
2930
2917
2931
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 );
2924
2943
}
2925
2944
Py_RETURN_NONE ;
2926
2945
}
@@ -2982,7 +3001,7 @@ bytearray_iter(PyObject *seq)
2982
3001
it = PyObject_GC_New (bytesiterobject , & PyByteArrayIter_Type );
2983
3002
if (it == NULL )
2984
3003
return NULL ;
2985
- it -> it_index = 0 ;
3004
+ it -> it_index = 0 ; // -1 indicates exhausted
2986
3005
it -> it_seq = (PyByteArrayObject * )Py_NewRef (seq );
2987
3006
_PyObject_GC_TRACK (it );
2988
3007
return (PyObject * )it ;
0 commit comments