< 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;

@@ -63,10 +62,18 @@
                                             jint off, jint len, jint timeout)
 {
     char BUF[MAX_BUFFER_LEN];
     char *bufP;
     jint fd, nread;
+    long prevtime = 0, newtime;
+    struct timeval t;
+    long _timeout = timeout;
+    
+     if (_timeout > 0) {
+        gettimeofday(&t, NULL);
+        prevtime = t.tv_sec * 1000  +  t.tv_usec / 1000;
+    }
 
     if (IS_NULL(fdObj)) {
         /* shouldn't this be a NullPointerException? -br */
         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                         "Socket closed");

@@ -97,12 +104,12 @@
         }
     } else {
         bufP = BUF;
     }
 
-    if (timeout) {
-        nread = NET_Timeout(fd, timeout);
+LABEL:  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) {

@@ -118,14 +125,23 @@
             if (bufP != BUF) {
                 free(bufP);
             }
             return -1;
         }
+        nread = NET_NonBlockingRead(fd, bufP, len);
+        if (nread == -1 && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
+            gettimeofday(&t, NULL);
+            newtime = t.tv_sec * 1000 + t.tv_usec / 1000;
+            _timeout -= newtime - prevtime;
+            if(_timeout > 0){
+                prevtime = newtime;
+                goto LABEL;
     }
-
+        }
+    } else { // no timeout set, it has to be blocking call.
     nread = NET_Read(fd, bufP, len);
-
+    }
     if (nread <= 0) {
         if (nread < 0) {
 
             switch (errno) {
                 case ECONNRESET:

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