Blame SOURCES/00287-fix-thread-hanging-on-inaccessible-nfs-server.patch

ae2451
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
ae2451
index 4a71a57ec0d..2b40ada195a 100644
ae2451
--- a/Modules/_io/fileio.c
ae2451
+++ b/Modules/_io/fileio.c
ae2451
@@ -146,9 +146,15 @@ dircheck(fileio* self, PyObject *nameobj)
ae2451
 {
ae2451
 #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
ae2451
     struct stat buf;
ae2451
+    int res;
ae2451
     if (self->fd < 0)
ae2451
         return 0;
ae2451
-    if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) {
ae2451
+
ae2451
+    Py_BEGIN_ALLOW_THREADS
ae2451
+    res = fstat(self->fd, &buf;;
ae2451
+    Py_END_ALLOW_THREADS
ae2451
+
ae2451
+    if (res == 0 && S_ISDIR(buf.st_mode)) {
ae2451
         errno = EISDIR;
ae2451
         PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj);
ae2451
         return -1;
ae2451
@@ -162,17 +168,34 @@ check_fd(int fd)
ae2451
 {
ae2451
 #if defined(HAVE_FSTAT)
ae2451
     struct stat buf;
ae2451
-    if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) {
ae2451
-        PyObject *exc;
ae2451
-        char *msg = strerror(EBADF);
ae2451
-        exc = PyObject_CallFunction(PyExc_OSError, "(is)",
ae2451
-                                    EBADF, msg);
ae2451
-        PyErr_SetObject(PyExc_OSError, exc);
ae2451
-        Py_XDECREF(exc);
ae2451
-        return -1;
ae2451
+    int res;
ae2451
+    PyObject *exc;
ae2451
+    char *msg;
ae2451
+
ae2451
+    if (!_PyVerify_fd(fd)) {
ae2451
+        goto badfd;
ae2451
     }
ae2451
-#endif
ae2451
+
ae2451
+    Py_BEGIN_ALLOW_THREADS
ae2451
+    res = fstat(fd, &buf;;
ae2451
+    Py_END_ALLOW_THREADS
ae2451
+
ae2451
+    if (res < 0 && errno == EBADF) {
ae2451
+        goto badfd;
ae2451
+    }
ae2451
+
ae2451
     return 0;
ae2451
+
ae2451
+badfd:
ae2451
+    msg = strerror(EBADF);
ae2451
+    exc = PyObject_CallFunction(PyExc_OSError, "(is)",
ae2451
+                                EBADF, msg);
ae2451
+    PyErr_SetObject(PyExc_OSError, exc);
ae2451
+    Py_XDECREF(exc);
ae2451
+    return -1;
ae2451
+#else
ae2451
+    return 0;
ae2451
+#endif
ae2451
 }
ae2451
 
ae2451
 
ae2451
@@ -519,9 +542,19 @@ new_buffersize(fileio *self, size_t currentsize)
ae2451
 #ifdef HAVE_FSTAT
ae2451
     off_t pos, end;
ae2451
     struct stat st;
ae2451
-    if (fstat(self->fd, &st) == 0) {
ae2451
+    int res;
ae2451
+
ae2451
+    Py_BEGIN_ALLOW_THREADS
ae2451
+    res = fstat(self->fd, &st);
ae2451
+    Py_END_ALLOW_THREADS
ae2451
+
ae2451
+    if (res == 0) {
ae2451
         end = st.st_size;
ae2451
+
ae2451
+        Py_BEGIN_ALLOW_THREADS
ae2451
         pos = lseek(self->fd, 0L, SEEK_CUR);
ae2451
+        Py_END_ALLOW_THREADS
ae2451
+
ae2451
         /* Files claiming a size smaller than SMALLCHUNK may
ae2451
            actually be streaming pseudo-files. In this case, we
ae2451
            apply the more aggressive algorithm below.
ae2451
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
ae2451
index 2f63c374d1e..8d1c5812f0d 100644
ae2451
--- a/Objects/fileobject.c
ae2451
+++ b/Objects/fileobject.c
ae2451
@@ -121,10 +121,15 @@ dircheck(PyFileObject* f)
ae2451
 {
ae2451
 #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR)
ae2451
     struct stat buf;
ae2451
+    int res;
ae2451
     if (f->f_fp == NULL)
ae2451
         return f;
ae2451
-    if (fstat(fileno(f->f_fp), &buf) == 0 &&
ae2451
-        S_ISDIR(buf.st_mode)) {
ae2451
+
ae2451
+    Py_BEGIN_ALLOW_THREADS
ae2451
+    res = fstat(fileno(f->f_fp), &buf;;
ae2451
+    Py_END_ALLOW_THREADS
ae2451
+
ae2451
+    if (res == 0 && S_ISDIR(buf.st_mode)) {
ae2451
         char *msg = strerror(EISDIR);
ae2451
         PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(isO)",
ae2451
                                               EISDIR, msg, f->f_name);
ae2451
@@ -1010,7 +1015,13 @@ new_buffersize(PyFileObject *f, size_t currentsize)
ae2451
 #ifdef HAVE_FSTAT
ae2451
     off_t pos, end;
ae2451
     struct stat st;
ae2451
-    if (fstat(fileno(f->f_fp), &st) == 0) {
ae2451
+    int res;
ae2451
+
ae2451
+    Py_BEGIN_ALLOW_THREADS
ae2451
+    res = fstat(fileno(f->f_fp), &st);
ae2451
+    Py_END_ALLOW_THREADS
ae2451
+
ae2451
+    if (res == 0) {
ae2451
         end = st.st_size;
ae2451
         /* The following is not a bug: we really need to call lseek()
ae2451
            *and* ftell().  The reason is that some stdio libraries
ae2451
@@ -1021,7 +1032,11 @@ new_buffersize(PyFileObject *f, size_t currentsize)
ae2451
            works.  We can't use the lseek() value either, because we
ae2451
            need to take the amount of buffered data into account.
ae2451
            (Yet another reason why stdio stinks. :-) */
ae2451
+
ae2451
+        Py_BEGIN_ALLOW_THREADS
ae2451
         pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR);
ae2451
+        Py_END_ALLOW_THREADS
ae2451
+
ae2451
         if (pos >= 0) {
ae2451
             pos = ftell(f->f_fp);
ae2451
         }