]> granicus.if.org Git - python/commitdiff
bpo-32186: Release the GIL during lseek and fstat (#4652)
authorNir Soffer <nirsof@gmail.com>
Fri, 1 Dec 2017 01:18:58 +0000 (03:18 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Fri, 1 Dec 2017 01:18:58 +0000 (02:18 +0100)
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.

Misc/NEWS.d/next/Library/2017-11-30-20-38-16.bpo-32186.O42bVe.rst [new file with mode: 0644]
Modules/_io/fileio.c

diff --git a/Misc/NEWS.d/next/Library/2017-11-30-20-38-16.bpo-32186.O42bVe.rst b/Misc/NEWS.d/next/Library/2017-11-30-20-38-16.bpo-32186.O42bVe.rst
new file mode 100644 (file)
index 0000000..ea696c6
--- /dev/null
@@ -0,0 +1,3 @@
+io.FileIO.readall() and io.FileIO.read() now release the GIL when
+getting the file size. Fixed hang of all threads with inaccessible NFS
+server.  Patch by Nir Soffer.
index b6755b851dca8ed0c4d9a3e1dc7978ddb7793dcc..269142cfee5242c0909d55b8331a408948baeda9 100644 (file)
@@ -683,10 +683,12 @@ _io_FileIO_readall_impl(fileio *self)
     Py_ssize_t bytes_read = 0;
     Py_ssize_t n;
     size_t bufsize;
+    int fstat_result;
 
     if (self->fd < 0)
         return err_closed();
 
+    Py_BEGIN_ALLOW_THREADS
     _Py_BEGIN_SUPPRESS_IPH
 #ifdef MS_WINDOWS
     pos = _lseeki64(self->fd, 0L, SEEK_CUR);
@@ -694,8 +696,10 @@ _io_FileIO_readall_impl(fileio *self)
     pos = lseek(self->fd, 0L, SEEK_CUR);
 #endif
     _Py_END_SUPPRESS_IPH
+    fstat_result = _Py_fstat_noraise(self->fd, &status);
+    Py_END_ALLOW_THREADS
 
-    if (_Py_fstat_noraise(self->fd, &status) == 0)
+    if (fstat_result == 0)
         end = status.st_size;
     else
         end = (Py_off_t)-1;