@@ -16193,7 +16193,7 @@ typedef struct {
1619316193#ifdef  HAVE_FDOPENDIR 
1619416194    int  fd ;
1619516195#endif 
16196-     _PyRecursiveMutex  mutex ;
16196+     PyMutex  mutex ;
1619716197} ScandirIterator ;
1619816198
1619916199#define  ScandirIterator_CAST (op )    ((ScandirIterator *)(op))
@@ -16209,10 +16209,10 @@ ScandirIterator_is_closed(ScandirIterator *iterator)
1620916209static  void 
1621016210ScandirIterator_closedir (ScandirIterator  * iterator )
1621116211{
16212-     _PyRecursiveMutex_Lock (& iterator -> mutex );
16212+     PyMutex_Lock (& iterator -> mutex );
1621316213    HANDLE  handle  =  iterator -> handle ;
1621416214    iterator -> handle  =  INVALID_HANDLE_VALUE ;
16215-     _PyRecursiveMutex_Unlock (& iterator -> mutex );
16215+     PyMutex_Unlock (& iterator -> mutex );
1621616216
1621716217    if  (handle  ==  INVALID_HANDLE_VALUE ) {
1621816218        return ;
@@ -16223,46 +16223,56 @@ ScandirIterator_closedir(ScandirIterator *iterator)
1622316223    Py_END_ALLOW_THREADS 
1622416224}
1622516225
16226+ static  BOOL 
16227+ ScandirIterator_nextdirentry (ScandirIterator  * iterator , WIN32_FIND_DATAW  * file_data )
16228+ {
16229+     BOOL  has_error  =  FALSE;
16230+     BOOL  has_result  =  FALSE;
16231+     PyMutex_Lock (& iterator -> mutex );
16232+     if  (iterator -> handle  !=  INVALID_HANDLE_VALUE ) {
16233+         if  (iterator -> first_time ) {
16234+             has_result  =  TRUE;
16235+             memcpy (file_data , & iterator -> file_data , sizeof (WIN32_FIND_DATAW ));
16236+             iterator -> first_time  =  0 ;
16237+         } else  {
16238+             Py_BEGIN_ALLOW_THREADS 
16239+             has_result  =  FindNextFileW (iterator -> handle , file_data );
16240+             Py_END_ALLOW_THREADS 
16241+             has_error  =  !has_result  &&  GetLastError () !=  ERROR_NO_MORE_FILES ;
16242+         }
16243+     }
16244+     PyMutex_Unlock (& iterator -> mutex );
16245+ 
16246+     /* Error or no more files */ 
16247+     if  (has_error )
16248+         path_error (& iterator -> path );
16249+ 
16250+     return  has_result ;
16251+ }
16252+ 
1622616253static  PyObject  * 
1622716254ScandirIterator_iternext (PyObject  * op )
1622816255{
1622916256    ScandirIterator  * iterator  =  ScandirIterator_CAST (op );
16230-     WIN32_FIND_DATAW  * file_data  =  & iterator -> file_data ;
16231-     BOOL  success ;
16257+     WIN32_FIND_DATAW  file_data ;
1623216258    PyObject  * entry ;
1623316259
16234-     _PyRecursiveMutex_Lock (& iterator -> mutex );
16235-     while  (iterator -> handle  !=  INVALID_HANDLE_VALUE ) {
16236-         if  (!iterator -> first_time ) {
16237-             Py_BEGIN_ALLOW_THREADS 
16238-             success  =  FindNextFileW (iterator -> handle , file_data );
16239-             Py_END_ALLOW_THREADS 
16240-             if  (!success ) {
16241-                 /* Error or no more files */ 
16242-                 if  (GetLastError () !=  ERROR_NO_MORE_FILES )
16243-                     path_error (& iterator -> path );
16244-                 break ;
16245-             }
16246-         }
16247-         iterator -> first_time  =  0 ;
16248- 
16260+     while  (ScandirIterator_nextdirentry (iterator , & file_data )) {
1624916261        /* Skip over . and .. */ 
16250-         if  (wcscmp (file_data -> cFileName , L"." ) !=  0  && 
16251-             wcscmp (file_data -> cFileName , L".." ) !=  0 )
16262+         if  (wcscmp (file_data . cFileName , L"." ) !=  0  && 
16263+             wcscmp (file_data . cFileName , L".." ) !=  0 )
1625216264        {
1625316265            PyObject  * module  =  PyType_GetModule (Py_TYPE (iterator ));
16254-             entry  =  DirEntry_from_find_data (module , & iterator -> path , file_data );
16266+             entry  =  DirEntry_from_find_data (module , & iterator -> path , & file_data );
1625516267            if  (!entry )
1625616268                break ;
16257-             _PyRecursiveMutex_Unlock (& iterator -> mutex );
1625816269            return  entry ;
1625916270        }
1626016271
1626116272        /* Loop till we get a non-dot directory or finish iterating */ 
1626216273    }
1626316274
1626416275    /* Already closed, error, or no more files */ 
16265-     _PyRecursiveMutex_Unlock (& iterator -> mutex );
1626616276    ScandirIterator_closedir (iterator );
1626716277    return  NULL ;
1626816278}
@@ -16278,10 +16288,10 @@ ScandirIterator_is_closed(ScandirIterator *iterator)
1627816288static  void 
1627916289ScandirIterator_closedir (ScandirIterator  * iterator )
1628016290{
16281-     _PyRecursiveMutex_Lock (& iterator -> mutex );
16291+     PyMutex_Lock (& iterator -> mutex );
1628216292    DIR  * dirp  =  iterator -> dirp ;
1628316293    iterator -> dirp  =  NULL ;
16284-     _PyRecursiveMutex_Unlock (& iterator -> mutex );
16294+     PyMutex_Unlock (& iterator -> mutex );
1628516295
1628616296    if  (!dirp ) {
1628716297        return ;
@@ -16297,53 +16307,63 @@ ScandirIterator_closedir(ScandirIterator *iterator)
1629716307    return ;
1629816308}
1629916309
16310+ static  int 
16311+ ScandirIterator_nextdirentry (ScandirIterator  * iterator , struct  dirent  * direntp )
16312+ {
16313+     int  has_error  =  0 ;
16314+     struct  dirent  * result  =  NULL ;
16315+     PyMutex_Lock (& iterator -> mutex );
16316+     if  (iterator -> dirp ) {
16317+         errno  =  0 ;
16318+         Py_BEGIN_ALLOW_THREADS 
16319+         result  =  readdir (iterator -> dirp );
16320+         Py_END_ALLOW_THREADS 
16321+         has_error  =  !result  &&  errno  !=  0 ;
16322+     }
16323+     /* We need to make a copy of the result before releasing the lock */ 
16324+     if  (result )
16325+         memcpy (direntp , result , sizeof (struct  dirent ));
16326+     PyMutex_Unlock (& iterator -> mutex );
16327+ 
16328+     /* Error or no more files */ 
16329+     if  (has_error )
16330+         path_error (& iterator -> path );
16331+ 
16332+     return  result  !=  NULL ;
16333+ }
16334+ 
1630016335static  PyObject  * 
1630116336ScandirIterator_iternext (PyObject  * op )
1630216337{
1630316338    ScandirIterator  * iterator  =  ScandirIterator_CAST (op );
16304-     struct  dirent  * direntp ;
16339+     struct  dirent  direntp ;
1630516340    Py_ssize_t  name_len ;
1630616341    int  is_dot ;
1630716342    PyObject  * entry ;
1630816343
16309-     _PyRecursiveMutex_Lock (& iterator -> mutex );
16310-     while  (iterator -> dirp ) {
16311-         errno  =  0 ;
16312-         Py_BEGIN_ALLOW_THREADS 
16313-         direntp  =  readdir (iterator -> dirp );
16314-         Py_END_ALLOW_THREADS 
16315- 
16316-         if  (!direntp ) {
16317-             /* Error or no more files */ 
16318-             if  (errno  !=  0 )
16319-                 path_error (& iterator -> path );
16320-             break ;
16321-         }
16322- 
16344+     while  ((ScandirIterator_nextdirentry (iterator , & direntp ))) {
1632316345        /* Skip over . and .. */ 
16324-         name_len  =  NAMLEN (direntp );
16325-         is_dot  =  direntp -> d_name [0 ] ==  '.'  && 
16326-                  (name_len  ==  1  ||  (direntp -> d_name [1 ] ==  '.'  &&  name_len  ==  2 ));
16346+         name_len  =  NAMLEN (& direntp );
16347+         is_dot  =  direntp . d_name [0 ] ==  '.'  && 
16348+                  (name_len  ==  1  ||  (direntp . d_name [1 ] ==  '.'  &&  name_len  ==  2 ));
1632716349        if  (!is_dot ) {
1632816350            PyObject  * module  =  PyType_GetModule (Py_TYPE (iterator ));
1632916351            entry  =  DirEntry_from_posix_info (module ,
16330-                                              & iterator -> path , direntp -> d_name ,
16331-                                              name_len , direntp -> d_ino 
16352+                                              & iterator -> path , direntp . d_name ,
16353+                                              name_len , direntp . d_ino 
1633216354#ifdef  HAVE_DIRENT_D_TYPE 
16333-                                              , direntp -> d_type 
16355+                                              , direntp . d_type 
1633416356#endif 
1633516357                                            );
1633616358            if  (!entry )
1633716359                break ;
16338-             _PyRecursiveMutex_Unlock (& iterator -> mutex );
1633916360            return  entry ;
1634016361        }
1634116362
1634216363        /* Loop till we get a non-dot directory or finish iterating */ 
1634316364    }
1634416365
1634516366    /* Already closed, error, or no more files */ 
16346-     _PyRecursiveMutex_Unlock (& iterator -> mutex );
1634716367    ScandirIterator_closedir (iterator );
1634816368    return  NULL ;
1634916369}
@@ -16476,7 +16496,7 @@ os_scandir_impl(PyObject *module, path_t *path)
1647616496    if  (!iterator )
1647716497        return  NULL ;
1647816498
16479-     iterator -> mutex  =  (_PyRecursiveMutex ){0 };
16499+     iterator -> mutex  =  (PyMutex ){0 };
1648016500#ifdef  MS_WINDOWS 
1648116501    iterator -> handle  =  INVALID_HANDLE_VALUE ;
1648216502#else 
0 commit comments