Blame SOURCES/8075484-pr3473-rh1490713.patch

a42b25
# HG changeset patch
a42b25
# User vtewari
a42b25
# Date 1508189111 -3600
a42b25
#      Mon Oct 16 22:25:11 2017 +0100
a42b25
# Node ID bcaa659478ccac2b2ad1a817e03cab777949775a
a42b25
# Parent  161fbe4c53ff12328565487e69a608e15f39bd49
a42b25
8075484, PR3473, RH1490713: SocketInputStream.socketRead0 can hang even with soTimeout set
a42b25
Reviewed-by: chegar, dsamersoff, msheppar, clanger
a42b25
a42b25
diff --git a/src/aix/native/java/net/aix_close.c b/src/aix/native/java/net/aix_close.c
a42b25
--- openjdk/jdk/src/aix/native/java/net/aix_close.c
a42b25
+++ openjdk/jdk/src/aix/native/java/net/aix_close.c
a42b25
@@ -1,5 +1,6 @@
a42b25
 /*
a42b25
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
a42b25
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
a42b25
+ * Copyright (c) 2016, SAP SE and/or its affiliates. All rights reserved.
a42b25
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a42b25
  *
a42b25
  * This code is free software; you can redistribute it and/or modify it
a42b25
@@ -328,6 +329,10 @@
a42b25
     BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
a42b25
 }
a42b25
 
a42b25
+int NET_NonBlockingRead(int s, void* buf, size_t len) {
a42b25
+    BLOCKING_IO_RETURN_INT(s, recv(s, buf, len, MSG_NONBLOCK));
a42b25
+}
a42b25
+
a42b25
 int NET_ReadV(int s, const struct iovec * vector, int count) {
a42b25
     BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
a42b25
 }
a42b25
@@ -429,8 +434,8 @@
a42b25
  * Auto restarts with adjusted timeout if interrupted by
a42b25
  * signal other than our wakeup signal.
a42b25
  */
a42b25
-int NET_Timeout(int s, long timeout) {
a42b25
-    long prevtime = 0, newtime;
a42b25
+int NET_Timeout0(int s, long timeout, long currentTime) {
a42b25
+    long prevtime = currentTime, newtime;
a42b25
     struct timeval t;
a42b25
     fdEntry_t *fdEntry = getFdEntry(s);
a42b25
 
a42b25
@@ -442,14 +447,6 @@
a42b25
         return -1;
a42b25
     }
a42b25
 
a42b25
-    /*
a42b25
-     * Pick up current time as may need to adjust timeout
a42b25
-     */
a42b25
-    if (timeout > 0) {
a42b25
-        gettimeofday(&t, NULL);
a42b25
-        prevtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
a42b25
-    }
a42b25
-
a42b25
     for(;;) {
a42b25
         struct pollfd pfd;
a42b25
         int rv;
a42b25
diff --git a/src/solaris/native/java/net/SocketInputStream.c b/src/solaris/native/java/net/SocketInputStream.c
a42b25
--- openjdk/jdk/src/solaris/native/java/net/SocketInputStream.c
a42b25
+++ openjdk/jdk/src/solaris/native/java/net/SocketInputStream.c
a42b25
@@ -1,5 +1,5 @@
a42b25
 /*
a42b25
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
a42b25
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
a42b25
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a42b25
  *
a42b25
  * This code is free software; you can redistribute it and/or modify it
a42b25
@@ -52,6 +52,42 @@
a42b25
     IO_fd_fdID = NET_GetFileDescriptorID(env);
a42b25
 }
a42b25
 
a42b25
+#if !defined(__solaris__)
a42b25
+static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {
a42b25
+    int result = 0;
a42b25
+    long prevtime = NET_GetCurrentTime(), newtime;
a42b25
+    while (timeout > 0) {
a42b25
+        result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime);
a42b25
+        if (result <= 0) {
a42b25
+            if (result == 0) {
a42b25
+                JNU_ThrowByName(env, "java/net/SocketTimeoutException", "Read timed out");
a42b25
+            } else if (result == -1) {
a42b25
+                if (errno == EBADF) {
a42b25
+                    JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
a42b25
+                } else if (errno == ENOMEM) {
a42b25
+                    JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
a42b25
+                } else {
a42b25
+                    JNU_ThrowByNameWithMessageAndLastError
a42b25
+                            (env, "java/net/SocketException", "select/poll failed");
a42b25
+                }
a42b25
+            }
a42b25
+            return -1;
a42b25
+        }
a42b25
+        result = NET_NonBlockingRead(fd, bufP, len);
a42b25
+        if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
a42b25
+            newtime = NET_GetCurrentTime();
a42b25
+            timeout -= newtime - prevtime;
a42b25
+            if (timeout > 0) {
a42b25
+                prevtime = newtime;
a42b25
+            }
a42b25
+        } else {
a42b25
+            break;
a42b25
+        }
a42b25
+    }
a42b25
+    return result;
a42b25
+}
a42b25
+#endif
a42b25
+
a42b25
 /*
a42b25
  * Class:     java_net_SocketInputStream
a42b25
  * Method:    socketRead0
a42b25
@@ -99,6 +135,7 @@
a42b25
         bufP = BUF;
a42b25
     }
a42b25
 
a42b25
+#if defined(__solaris__)
a42b25
     if (timeout) {
a42b25
         nread = NET_Timeout(fd, timeout);
a42b25
         if (nread <= 0) {
a42b25
@@ -126,7 +163,19 @@
a42b25
     }
a42b25
 
a42b25
     nread = NET_Read(fd, bufP, len);
a42b25
-
a42b25
+#else
a42b25
+    if (timeout) {
a42b25
+        nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);
a42b25
+        if ((*env)->ExceptionCheck(env)) {
a42b25
+            if (bufP != BUF) {
a42b25
+                free(bufP);
a42b25
+            }
a42b25
+            return nread;
a42b25
+        }
a42b25
+    } else {
a42b25
+        nread = NET_Read(fd, bufP, len);
a42b25
+    }
a42b25
+#endif
a42b25
     if (nread <= 0) {
a42b25
         if (nread < 0) {
a42b25
 
a42b25
diff --git a/src/solaris/native/java/net/bsd_close.c b/src/solaris/native/java/net/bsd_close.c
a42b25
--- openjdk/jdk/src/solaris/native/java/net/bsd_close.c
a42b25
+++ openjdk/jdk/src/solaris/native/java/net/bsd_close.c
a42b25
@@ -1,5 +1,5 @@
a42b25
 /*
a42b25
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
a42b25
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
a42b25
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a42b25
  *
a42b25
  * This code is free software; you can redistribute it and/or modify it
a42b25
@@ -292,6 +292,10 @@
a42b25
     BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
a42b25
 }
a42b25
 
a42b25
+int NET_NonBlockingRead(int s, void* buf, size_t len) {
a42b25
+    BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT));
a42b25
+}
a42b25
+
a42b25
 int NET_ReadV(int s, const struct iovec * vector, int count) {
a42b25
     BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
a42b25
 }
a42b25
@@ -344,8 +348,8 @@
a42b25
  * Auto restarts with adjusted timeout if interrupted by
a42b25
  * signal other than our wakeup signal.
a42b25
  */
a42b25
-int NET_Timeout(int s, long timeout) {
a42b25
-    long prevtime = 0, newtime;
a42b25
+int NET_Timeout0(int s, long timeout, long currentTime) {
a42b25
+    long prevtime = currentTime, newtime;
a42b25
     struct timeval t, *tp = &t;
a42b25
     fd_set fds;
a42b25
     fd_set* fdsp = NULL;
a42b25
@@ -366,9 +370,6 @@
a42b25
      */
a42b25
     if (timeout > 0) {
a42b25
         /* Timed */
a42b25
-        struct timeval now;
a42b25
-        gettimeofday(&now, NULL);
a42b25
-        prevtime = now.tv_sec * 1000  +  now.tv_usec / 1000;
a42b25
         t.tv_sec = timeout / 1000;
a42b25
         t.tv_usec = (timeout % 1000) * 1000;
a42b25
     } else if (timeout < 0) {
a42b25
diff --git a/src/solaris/native/java/net/linux_close.c b/src/solaris/native/java/net/linux_close.c
a42b25
--- openjdk/jdk/src/solaris/native/java/net/linux_close.c
a42b25
+++ openjdk/jdk/src/solaris/native/java/net/linux_close.c
a42b25
@@ -1,5 +1,5 @@
a42b25
 /*
a42b25
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
a42b25
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
a42b25
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a42b25
  *
a42b25
  * This code is free software; you can redistribute it and/or modify it
a42b25
@@ -273,6 +273,10 @@
a42b25
     BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) );
a42b25
 }
a42b25
 
a42b25
+int NET_NonBlockingRead(int s, void* buf, size_t len) {
a42b25
+    BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT) );
a42b25
+}
a42b25
+
a42b25
 int NET_ReadV(int s, const struct iovec * vector, int count) {
a42b25
     BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
a42b25
 }
a42b25
@@ -324,8 +328,8 @@
a42b25
  * Auto restarts with adjusted timeout if interrupted by
a42b25
  * signal other than our wakeup signal.
a42b25
  */
a42b25
-int NET_Timeout(int s, long timeout) {
a42b25
-    long prevtime = 0, newtime;
a42b25
+int NET_Timeout0(int s, long timeout, long currentTime) {
a42b25
+    long prevtime = currentTime, newtime;
a42b25
     struct timeval t;
a42b25
     fdEntry_t *fdEntry = getFdEntry(s);
a42b25
 
a42b25
@@ -337,14 +341,6 @@
a42b25
         return -1;
a42b25
     }
a42b25
 
a42b25
-    /*
a42b25
-     * Pick up current time as may need to adjust timeout
a42b25
-     */
a42b25
-    if (timeout > 0) {
a42b25
-        gettimeofday(&t, NULL);
a42b25
-        prevtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
a42b25
-    }
a42b25
-
a42b25
     for(;;) {
a42b25
         struct pollfd pfd;
a42b25
         int rv;
a42b25
diff --git a/src/solaris/native/java/net/net_util_md.c b/src/solaris/native/java/net/net_util_md.c
a42b25
--- openjdk/jdk/src/solaris/native/java/net/net_util_md.c
a42b25
+++ openjdk/jdk/src/solaris/native/java/net/net_util_md.c
a42b25
@@ -33,6 +33,7 @@
a42b25
 #include <netdb.h>
a42b25
 #include <stdlib.h>
a42b25
 #include <dlfcn.h>
a42b25
+#include <sys/time.h>
a42b25
 
a42b25
 #ifndef _ALLBSD_SOURCE
a42b25
 #include <values.h>
a42b25
@@ -1661,3 +1662,20 @@
a42b25
 
a42b25
     return timeout;
a42b25
 }
a42b25
+
a42b25
+#if !defined(__solaris__)
a42b25
+long NET_GetCurrentTime() {
a42b25
+    struct timeval time;
a42b25
+    gettimeofday(&time, NULL);
a42b25
+    return (time.tv_sec * 1000 + time.tv_usec / 1000);
a42b25
+}
a42b25
+
a42b25
+int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime) {
a42b25
+    return NET_Timeout0(s, timeout, currentTime);
a42b25
+}
a42b25
+
a42b25
+int NET_Timeout(int s, long timeout) {
a42b25
+    long currentTime = (timeout > 0) ? NET_GetCurrentTime() : 0;
a42b25
+    return NET_Timeout0(s, timeout, currentTime);
a42b25
+}
a42b25
+#endif
a42b25
diff --git a/src/solaris/native/java/net/net_util_md.h b/src/solaris/native/java/net/net_util_md.h
a42b25
--- openjdk/jdk/src/solaris/native/java/net/net_util_md.h
a42b25
+++ openjdk/jdk/src/solaris/native/java/net/net_util_md.h
a42b25
@@ -47,9 +47,13 @@
a42b25
    close subroutine does not return until the select call returns.
a42b25
    ...
a42b25
 */
a42b25
-#if defined(__linux__) || defined(MACOSX) || defined (_AIX)
a42b25
+#if !defined(__solaris__)
a42b25
 extern int NET_Timeout(int s, long timeout);
a42b25
+extern int NET_Timeout0(int s, long timeout, long currentTime);
a42b25
 extern int NET_Read(int s, void* buf, size_t len);
a42b25
+extern int NET_NonBlockingRead(int s, void* buf, size_t len);
a42b25
+extern int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime);
a42b25
+extern long NET_GetCurrentTime();
a42b25
 extern int NET_RecvFrom(int s, void *buf, int len, unsigned int flags,
a42b25
        struct sockaddr *from, int *fromlen);
a42b25
 extern int NET_ReadV(int s, const struct iovec * vector, int count);