Skip to content

Commit 8bcd410

Browse files
miss-islingtonvstinner
authored andcommitted
bpo-32186: Release the GIL during lseek and fstat (GH-4652) (#4661)
In _io_FileIO_readall_impl(), lseek() and _Py_fstat_noraise() were called without releasing the GIL. This can cause all threads to hang for unlimited time when calling FileIO.read() and the NFS server is not accessible. (cherry picked from commit 6a89481)
1 parent e10c9de commit 8bcd410

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
io.FileIO.readall() and io.FileIO.read() now release the GIL when
2+
getting the file size. Fixed hang of all threads with inaccessible NFS
3+
server. Patch by Nir Soffer.

Modules/_io/fileio.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,19 +691,23 @@ _io_FileIO_readall_impl(fileio *self)
691691
Py_ssize_t bytes_read = 0;
692692
Py_ssize_t n;
693693
size_t bufsize;
694+
int fstat_result;
694695

695696
if (self->fd < 0)
696697
return err_closed();
697698

699+
Py_BEGIN_ALLOW_THREADS
698700
_Py_BEGIN_SUPPRESS_IPH
699701
#ifdef MS_WINDOWS
700702
pos = _lseeki64(self->fd, 0L, SEEK_CUR);
701703
#else
702704
pos = lseek(self->fd, 0L, SEEK_CUR);
703705
#endif
704706
_Py_END_SUPPRESS_IPH
707+
fstat_result = _Py_fstat_noraise(self->fd, &status);
708+
Py_END_ALLOW_THREADS
705709

706-
if (_Py_fstat_noraise(self->fd, &status) == 0)
710+
if (fstat_result == 0)
707711
end = status.st_size;
708712
else
709713
end = (Py_off_t)-1;

0 commit comments

Comments
 (0)