@@ -55,6 +55,8 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5555#include "pycore_pyhash.h" // _Py_HashSecret_t
5656#include "pycore_pylifecycle.h" // _Py_SetFileSystemEncoding()
5757#include "pycore_pystate.h" // _PyInterpreterState_GET()
58+ #include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_*()
59+ #include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
5860#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI
5961#include "pycore_unicodectype.h" // _PyUnicode_IsXidStart
6062#include "pycore_unicodeobject.h" // struct _Py_unicode_state
@@ -14968,21 +14970,30 @@ unicodeiter_next(PyObject *op)
1496814970 PyObject * seq ;
1496914971
1497014972 assert (it != NULL );
14973+ #ifdef Py_GIL_DISABLED
14974+ seq = _Py_atomic_load_ptr (& it -> it_seq );
14975+ #else
1497114976 seq = it -> it_seq ;
14977+ #endif
1497214978 if (seq == NULL )
1497314979 return NULL ;
1497414980 assert (_PyUnicode_CHECK (seq ));
1497514981
14976- if (it -> it_index < PyUnicode_GET_LENGTH (seq )) {
14982+ Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> it_index );
14983+ if (index < PyUnicode_GET_LENGTH (seq )) {
1497714984 int kind = PyUnicode_KIND (seq );
1497814985 const void * data = PyUnicode_DATA (seq );
14979- Py_UCS4 chr = PyUnicode_READ (kind , data , it -> it_index );
14980- it -> it_index ++ ;
14986+ Py_UCS4 chr = PyUnicode_READ (kind , data , index );
14987+ FT_ATOMIC_STORE_SSIZE_RELAXED ( it -> it_index , index + 1 ) ;
1498114988 return unicode_char (chr );
1498214989 }
1498314990
14991+ #ifdef Py_GIL_DISABLED
14992+ seq = _Py_atomic_exchange_ptr (& it -> it_seq , NULL );
14993+ #else
1498414994 it -> it_seq = NULL ;
14985- Py_DECREF (seq );
14995+ #endif
14996+ Py_XDECREF (seq );
1498614997 return NULL ;
1498714998}
1498814999
@@ -14991,21 +15002,32 @@ unicode_ascii_iter_next(PyObject *op)
1499115002{
1499215003 unicodeiterobject * it = (unicodeiterobject * )op ;
1499315004 assert (it != NULL );
15005+ #ifdef Py_GIL_DISABLED
15006+ PyObject * seq = _Py_atomic_load_ptr (& it -> it_seq );
15007+ #else
1499415008 PyObject * seq = it -> it_seq ;
15009+ #endif
1499515010 if (seq == NULL ) {
1499615011 return NULL ;
1499715012 }
1499815013 assert (_PyUnicode_CHECK (seq ));
1499915014 assert (PyUnicode_IS_COMPACT_ASCII (seq ));
15000- if (it -> it_index < PyUnicode_GET_LENGTH (seq )) {
15015+
15016+ Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> it_index );
15017+ if (index < PyUnicode_GET_LENGTH (seq )) {
1500115018 const void * data = ((void * )(_PyASCIIObject_CAST (seq ) + 1 ));
15002- Py_UCS1 chr = (Py_UCS1 )PyUnicode_READ (PyUnicode_1BYTE_KIND ,
15003- data , it -> it_index );
15004- it -> it_index ++ ;
15019+ Py_UCS1 chr = (Py_UCS1 )PyUnicode_READ (
15020+ PyUnicode_1BYTE_KIND , data , index );
15021+ FT_ATOMIC_STORE_SSIZE_RELAXED ( it -> it_index , index + 1 ) ;
1500515022 return (PyObject * )& _Py_SINGLETON (strings ).ascii [chr ];
1500615023 }
15024+
15025+ #ifdef Py_GIL_DISABLED
15026+ seq = _Py_atomic_exchange_ptr (& it -> it_seq , NULL );
15027+ #else
1500715028 it -> it_seq = NULL ;
15008- Py_DECREF (seq );
15029+ #endif
15030+ Py_XDECREF (seq );
1500915031 return NULL ;
1501015032}
1501115033
@@ -15014,8 +15036,22 @@ unicodeiter_len(PyObject *op, PyObject *Py_UNUSED(ignored))
1501415036{
1501515037 unicodeiterobject * it = (unicodeiterobject * )op ;
1501615038 Py_ssize_t len = 0 ;
15039+ #ifdef Py_GIL_DISABLED
15040+ PyObject * seq ;
15041+ Py_BEGIN_CRITICAL_SECTION (it );
15042+ seq = Py_XNewRef (it -> it_seq );
15043+ Py_END_CRITICAL_SECTION ();
15044+ if (seq != NULL ) {
15045+ Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> it_index );
15046+ Py_ssize_t seq_len = PyUnicode_GET_LENGTH (seq );
15047+ if (index < seq_len )
15048+ len = seq_len - index ;
15049+ Py_DECREF (seq );
15050+ }
15051+ #else
1501715052 if (it -> it_seq )
1501815053 len = PyUnicode_GET_LENGTH (it -> it_seq ) - it -> it_index ;
15054+ #endif
1501915055 return PyLong_FromSsize_t (len );
1502015056}
1502115057
@@ -15031,16 +15067,34 @@ unicodeiter_reduce(PyObject *op, PyObject *Py_UNUSED(ignored))
1503115067 * call must be before access of iterator pointers.
1503215068 * see issue #101765 */
1503315069
15070+ #ifdef Py_GIL_DISABLED
15071+ PyObject * seq ;
15072+ Py_ssize_t index ;
15073+ Py_BEGIN_CRITICAL_SECTION (it );
15074+ seq = Py_XNewRef (it -> it_seq );
15075+ index = FT_ATOMIC_LOAD_SSIZE_RELAXED (it -> it_index );
15076+ Py_END_CRITICAL_SECTION ();
15077+
15078+ if (seq != NULL ) {
15079+ if (index < PyUnicode_GET_LENGTH (seq )) {
15080+ PyObject * result = Py_BuildValue ("N(O)n" , iter , seq , index );
15081+ Py_DECREF (seq );
15082+ return result ;
15083+ }
15084+ Py_DECREF (seq );
15085+ }
15086+ #else
1503415087 if (it -> it_seq != NULL ) {
1503515088 return Py_BuildValue ("N(O)n" , iter , it -> it_seq , it -> it_index );
15036- } else {
15037- PyObject * u = _PyUnicode_GetEmpty ();
15038- if (u == NULL ) {
15039- Py_XDECREF (iter );
15040- return NULL ;
15041- }
15042- return Py_BuildValue ("N(N)" , iter , u );
1504315089 }
15090+ #endif
15091+
15092+ PyObject * u = _PyUnicode_GetEmpty ();
15093+ if (u == NULL ) {
15094+ Py_XDECREF (iter );
15095+ return NULL ;
15096+ }
15097+ return Py_BuildValue ("N(N)" , iter , u );
1504415098}
1504515099
1504615100PyDoc_STRVAR (reduce_doc , "Return state information for pickling." );
@@ -15057,7 +15111,7 @@ unicodeiter_setstate(PyObject *op, PyObject *state)
1505715111 index = 0 ;
1505815112 else if (index > PyUnicode_GET_LENGTH (it -> it_seq ))
1505915113 index = PyUnicode_GET_LENGTH (it -> it_seq ); /* iterator truncated */
15060- it -> it_index = index ;
15114+ FT_ATOMIC_STORE_SSIZE_RELAXED ( it -> it_index , index ) ;
1506115115 }
1506215116 Py_RETURN_NONE ;
1506315117}
0 commit comments