@@ -15582,7 +15582,6 @@ typedef struct {
1558215582    ino_t  d_ino ;
1558315583    int  dir_fd ;
1558415584#endif 
15585-     _PyRecursiveMutex  mutex ;
1558615585} DirEntry ;
1558715586
1558815587#define  DirEntry_CAST (op )   ((DirEntry *)(op))
@@ -15592,12 +15591,10 @@ DirEntry_dealloc(PyObject *op)
1559215591{
1559315592    DirEntry  * entry  =  DirEntry_CAST (op );
1559415593    PyTypeObject  * tp  =  Py_TYPE (entry );
15595-     _PyRecursiveMutex_Lock (& entry -> mutex );
1559615594    Py_XDECREF (entry -> name );
1559715595    Py_XDECREF (entry -> path );
1559815596    Py_XDECREF (entry -> stat );
1559915597    Py_XDECREF (entry -> lstat );
15600-     _PyRecursiveMutex_Unlock (& entry -> mutex );
1560115598    freefunc  free_func  =  PyType_GetSlot (tp , Py_tp_free );
1560215599    free_func (entry );
1560315600    Py_DECREF (tp );
@@ -15715,16 +15712,19 @@ DirEntry_fetch_stat(PyObject *module, DirEntry *self, int follow_symlinks)
1571515712static  PyObject  * 
1571615713DirEntry_get_lstat (PyTypeObject  * defining_class , DirEntry  * self )
1571715714{
15718-     /* Must be called with self->mutex held */ 
15719-     if  (!self -> lstat ) {
15715+     if  (!FT_ATOMIC_LOAD_PTR (self -> lstat )) {
1572015716        PyObject  * module  =  PyType_GetModule (defining_class );
15717+         PyObject  * lstat ;
15718+         PyObject  * null_ptr  =  NULL ;
1572115719#ifdef  MS_WINDOWS 
15722-         self -> lstat  =  _pystat_fromstructstat (module , & self -> win32_lstat );
15720+         lstat  =  _pystat_fromstructstat (module , & self -> win32_lstat );
1572315721#else  /* POSIX */ 
15724-         self -> lstat  =  DirEntry_fetch_stat (module , self , 0 );
15722+         lstat  =  DirEntry_fetch_stat (module , self , 0 );
1572515723#endif 
15724+         if  (!_Py_atomic_compare_exchange_ptr (& self -> lstat , & null_ptr , lstat ))
15725+             Py_XDECREF (lstat );
1572615726    }
15727-     return  Py_XNewRef (self -> lstat );
15727+     return  Py_XNewRef (FT_ATOMIC_LOAD_PTR ( self -> lstat ) );
1572815728}
1572915729
1573015730/*[clinic input] 
@@ -15742,31 +15742,28 @@ os_DirEntry_stat_impl(DirEntry *self, PyTypeObject *defining_class,
1574215742                      int  follow_symlinks )
1574315743/*[clinic end generated code: output=23f803e19c3e780e input=e816273c4e67ee98]*/ 
1574415744{
15745-     if  (!follow_symlinks ) {
15746-         _PyRecursiveMutex_Lock (& self -> mutex );
15747-         PyObject  * stat  =  DirEntry_get_lstat (defining_class , self );
15748-         _PyRecursiveMutex_Unlock (& self -> mutex );
15749-         return  stat ;
15750-     }
15745+     if  (!follow_symlinks )
15746+         return  DirEntry_get_lstat (defining_class , self );
1575115747
15752-     _PyRecursiveMutex_Lock (& self -> mutex );
15753-     if  (!self -> stat ) {
15748+     if  (!FT_ATOMIC_LOAD_PTR (self -> stat )) {
15749+         PyObject  * stat ;
15750+         PyObject  * null_ptr  =  NULL ;
1575415751        int  result  =  os_DirEntry_is_symlink_impl (self , defining_class );
1575515752        if  (result  ==  -1 ) {
15756-             _PyRecursiveMutex_Unlock (& self -> mutex );
1575715753            return  NULL ;
1575815754        }
1575915755        if  (result ) {
1576015756            PyObject  * module  =  PyType_GetModule (defining_class );
15761-             self -> stat  =  DirEntry_fetch_stat (module , self , 1 );
15757+             stat  =  DirEntry_fetch_stat (module , self , 1 );
1576215758        }
1576315759        else  {
15764-             self -> stat  =  DirEntry_get_lstat (defining_class , self );
15760+             stat  =  DirEntry_get_lstat (defining_class , self );
1576515761        }
15762+         if  (!_Py_atomic_compare_exchange_ptr (& self -> stat , & null_ptr , stat ))
15763+             Py_XDECREF (stat );
1576615764    }
15767-     _PyRecursiveMutex_Unlock (& self -> mutex );
1576815765
15769-     return  Py_XNewRef (self -> stat );
15766+     return  Py_XNewRef (FT_ATOMIC_LOAD_PTR ( self -> stat ) );
1577015767}
1577115768
1577215769/* Set exception and return -1 on error, 0 for False, 1 for True */ 
@@ -16039,7 +16036,6 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
1603916036    entry -> stat  =  NULL ;
1604016037    entry -> lstat  =  NULL ;
1604116038    entry -> got_file_index  =  0 ;
16042-     entry -> mutex  =  (_PyRecursiveMutex ){0 };
1604316039
1604416040    entry -> name  =  PyUnicode_FromWideChar (dataW -> cFileName , -1 );
1604516041    if  (!entry -> name )
@@ -16132,7 +16128,6 @@ DirEntry_from_posix_info(PyObject *module, path_t *path, const char *name,
1613216128    entry -> path  =  NULL ;
1613316129    entry -> stat  =  NULL ;
1613416130    entry -> lstat  =  NULL ;
16135-     entry -> mutex  =  (_PyRecursiveMutex ){0 };
1613616131
1613716132    if  (path -> fd  !=  -1 ) {
1613816133        entry -> dir_fd  =  path -> fd ;
0 commit comments