[Python-checkins] bpo-32186: Release the GIL during lseek and fstat (GH-4652) (#4661)
Victor Stinner
webhook-mailer at python.org
Fri Dec 1 01:26:34 EST 2017
https://github.com/python/cpython/commit/8bcd41040a5f1f9b48a86d0e21f196e4b1f90e4b
commit: 8bcd41040a5f1f9b48a86d0e21f196e4b1f90e4b
branch: 3.6
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Victor Stinner <victor.stinner at gmail.com>
date: 2017年12月01日T07:26:31+01:00
summary:
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 6a89481680b921e7b317c29877bdda9a6031e5ad)
files:
A Misc/NEWS.d/next/Library/2017-11-30-20-38-16.bpo-32186.O42bVe.rst
M 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
index 00000000000..ea696c6098a
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2017-11-30-20-38-16.bpo-32186.O42bVe.rst
@@ -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.
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
index 918fa577758..52cbb94b24b 100644
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -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;
More information about the Python-checkins
mailing list