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

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