]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-32186: Release the GIL during lseek and fstat (GH-4652) (#4661)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 1 Dec 2017 06:26:31 +0000 (22:26 -0800)
committerVictor Stinner <victor.stinner@gmail.com>
Fri, 1 Dec 2017 06:26:31 +0000 (07:26 +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.
(cherry picked from commit 6a89481680b921e7b317c29877bdda9a6031e5ad)

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 918fa577758d2807f3e8afb9540c0c3486edc049..52cbb94b24b6b572e038d4c00caeb73108495606 100644 (file)
@@ -691,10 +691,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);
@@ -702,8 +704,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;