< prev index next >

src/java.base/unix/native/libnet/SocketInputStream.c

Print this page

        

@@ -26,18 +26,17 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
-
+#include <sys/time.h>
 #include "jvm.h"
 #include "jni_util.h"
 #include "net_util.h"
 
 #include "java_net_SocketInputStream.h"
 
-
 /************************************************************************
  * SocketInputStream
  */
 
 static jfieldID IO_fd_fdID;

@@ -50,10 +49,50 @@
 JNIEXPORT void JNICALL
 Java_java_net_SocketInputStream_init(JNIEnv *env, jclass cls) {
     IO_fd_fdID = NET_GetFileDescriptorID(env);
 }
 
+static long getCurrentTime() {
+    struct timeval time;
+    gettimeofday(&time, NULL);
+    return (time.tv_sec * 1000 + time.tv_usec / 1000);
+}
+
+static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {
+    int result = 0;
+    long prevtime = getCurrentTime(), newtime;
+    while (timeout > 0) {
+        result = NET_TimeoutWithCurrentTime(fd, timeout, prevtime);
+        if (result <= 0) {
+            if (result == 0) {
+                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException", "Read timed out");
+            } else if (result == -1) {
+                if (errno == EBADF) {
+                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
+                } else if (errno == ENOMEM) {
+                    JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
+                } else {
+                    JNU_ThrowByNameWithMessageAndLastError
+                            (env, JNU_JAVANETPKG "SocketException", "select/poll failed");
+                }
+            }
+            return -1;
+        }
+        result = NET_NonBlockingRead(fd, bufP, len);
+        if (result == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
+            newtime = getCurrentTime();
+            timeout -= newtime - prevtime;
+            if (timeout > 0) {
+                prevtime = newtime;
+            }
+        } else {
+            break;
+        }
+    }
+    return result;
+}
+
 /*
  * Class:     java_net_SocketInputStream
  * Method:    socketRead0
  * Signature: (Ljava/io/FileDescriptor;[BIII)I
  */

@@ -96,36 +135,21 @@
             len = MAX_BUFFER_LEN;
         }
     } else {
         bufP = BUF;
     }
-
     if (timeout) {
-        nread = NET_Timeout(fd, timeout);
-        if (nread <= 0) {
-            if (nread == 0) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                            "Read timed out");
-            } else if (nread == -1) {
-                if (errno == EBADF) {
-                     JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-                } else if (errno == ENOMEM) {
-                    JNU_ThrowOutOfMemoryError(env, "NET_Timeout native heap allocation failed");
+        nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);
                 } else {
-                    JNU_ThrowByNameWithMessageAndLastError
-                        (env, JNU_JAVANETPKG "SocketException", "select/poll failed");
-                }
+        nread = NET_Read(fd, bufP, len);
             }
+    if ((*env)->ExceptionCheck(env)) {
             if (bufP != BUF) {
                 free(bufP);
             }
-            return -1;
-        }
+        return nread;
     }
-
-    nread = NET_Read(fd, bufP, len);
-
     if (nread <= 0) {
         if (nread < 0) {
 
             switch (errno) {
                 case ECONNRESET:

@@ -141,11 +165,10 @@
 
                 case EINTR:
                      JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
                            "Operation interrupted");
                      break;
-
                 default:
                     JNU_ThrowByNameWithMessageAndLastError
                         (env, JNU_JAVANETPKG "SocketException", "Read failed");
             }
         }
< prev index next >