--- old/src/java.base/aix/native/libnet/aix_close.c 2016-09-07 18:50:52.393232513 +0530 +++ new/src/java.base/aix/native/libnet/aix_close.c 2016-09-07 18:50:51.933231738 +0530 @@ -410,6 +410,10 @@ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); } +int NET_NonBlockingRead(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT)); +} + int NET_ReadV(int s, const struct iovec * vector, int count) { BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); } @@ -503,8 +507,8 @@ * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; +int NET_Timeout0(int s, long timeout,long currentTime) { + long prevtime = currentTime, newtime; struct timeval t; fdEntry_t *fdEntry = getFdEntry(s); @@ -516,14 +520,6 @@ return -1; } - /* - * Pick up current time as may need to adjust timeout - */ - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; - } - for(;;) { struct pollfd pfd; int rv; @@ -560,3 +556,17 @@ } } + +int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime) { + return NET_Timeout0(s, timeout, currentTime); +} + +int NET_Timeout(int s, long timeout) { + long currentTime = 0; + struct timeval t; + if (timeout > 0) { + gettimeofday(&t, NULL); + currentTime = t.tv_sec * 1000 + t.tv_usec / 1000; + } + return NET_Timeout0(s, timeout, currentTime); +} --- old/src/java.base/linux/native/libnet/linux_close.c 2016-09-07 18:50:53.965235164 +0530 +++ new/src/java.base/linux/native/libnet/linux_close.c 2016-09-07 18:50:53.433234267 +0530 @@ -367,6 +367,10 @@ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); } +int NET_NonBlockingRead(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT) ); +} + int NET_ReadV(int s, const struct iovec * vector, int count) { BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); } @@ -406,8 +410,8 @@ * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; +int NET_Timeout0(int s, long timeout,long currentTime) { + long prevtime = currentTime, newtime; struct timeval t; fdEntry_t *fdEntry = getFdEntry(s); @@ -418,15 +422,7 @@ errno = EBADF; return -1; } - - /* - * Pick up current time as may need to adjust timeout - */ - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = t.tv_sec * 1000 + t.tv_usec / 1000; - } - + for(;;) { struct pollfd pfd; int rv; @@ -463,3 +459,17 @@ } } + +int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime) { + return NET_Timeout0(s, timeout, currentTime); +} + +int NET_Timeout(int s, long timeout) { + long currentTime = 0; + struct timeval t; + if (timeout > 0) { + gettimeofday(&t, NULL); + currentTime = t.tv_sec * 1000 + t.tv_usec / 1000; + } + return NET_Timeout0(s, timeout, currentTime); +} --- old/src/java.base/macosx/native/libnet/bsd_close.c 2016-09-07 18:50:55.273237369 +0530 +++ new/src/java.base/macosx/native/libnet/bsd_close.c 2016-09-07 18:50:54.813236594 +0530 @@ -371,6 +371,10 @@ BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, 0) ); } +int NET_NonBlockingRead(int s, void* buf, size_t len) { + BLOCKING_IO_RETURN_INT( s, recv(s, buf, len, MSG_DONTWAIT)); +} + int NET_ReadV(int s, const struct iovec * vector, int count) { BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) ); } @@ -410,8 +414,8 @@ * Auto restarts with adjusted timeout if interrupted by * signal other than our wakeup signal. */ -int NET_Timeout(int s, long timeout) { - long prevtime = 0, newtime; +int NET_Timeout0(int s, long timeout,long currentTime) { + long prevtime = currentTime, newtime; struct timeval t, *tp = &t; fd_set fds; fd_set* fdsp = NULL; @@ -432,9 +436,6 @@ */ if (timeout > 0) { /* Timed */ - struct timeval now; - gettimeofday(&now, NULL); - prevtime = now.tv_sec * 1000 + now.tv_usec / 1000; t.tv_sec = timeout / 1000; t.tv_usec = (timeout % 1000) * 1000; } else if (timeout < 0) { @@ -498,3 +499,17 @@ } } + +int NET_TimeoutWithCurrentTime(int s,long timeout,long currentTime){ + return NET_Timeout0(s, timeout, currentTime); +} + +int NET_Timeout(int s, long timeout) { + long currentTime = 0; + struct timeval t; + if (timeout > 0) { + gettimeofday(&t, NULL); + currentTime = t.tv_sec * 1000 + t.tv_usec / 1000; + } + return NET_Timeout0(s, timeout, currentTime); +} --- old/src/java.base/solaris/native/libnet/solaris_close.c 2016-09-07 18:50:56.517239468 +0530 +++ new/src/java.base/solaris/native/libnet/solaris_close.c 2016-09-07 18:50:56.081238732 +0530 @@ -35,7 +35,7 @@ if (1) { \ do { \ _result = _cmd; \ - } while((_result == -1) && (errno == EINTR)); \ + } while((_result == -1) && (errno == EINTR)); \ return _result; \ } \ } while(0) @@ -44,6 +44,10 @@ RESTARTABLE_RETURN_INT(recv(s, buf, len, 0)); } +int NET_NonBlockingRead(int s, void* buf, size_t len) { + RESTARTABLE_RETURN_INT(recv(s, buf, len, MSG_DONTWAIT)); +} + int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, socklen_t *fromlen) { RESTARTABLE_RETURN_INT(recvfrom(s, buf, len, flags, from, fromlen)); @@ -86,19 +90,14 @@ RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout)); } -int NET_Timeout(int s, long timeout) { +int NET_Timeout0(int s, long timeout,long currentTime) { int result; struct timeval t; - long prevtime, newtime; + long prevtime = currentTime, newtime; struct pollfd pfd; pfd.fd = s; pfd.events = POLLIN; - - if (timeout > 0) { - gettimeofday(&t, NULL); - prevtime = (t.tv_sec * 1000) + t.tv_usec / 1000; - } - + for(;;) { result = poll(&pfd, 1, timeout); if (result < 0 && errno == EINTR) { @@ -115,3 +114,17 @@ } } } + +int NET_TimeoutWithCurrentTime(int s,long timeout,long currentTime){ + return NET_Timeout0(s, timeout, currentTime); +} + +int NET_Timeout(int s, long timeout) { + long currentTime = 0; + struct timeval t; + if (timeout > 0) { + gettimeofday(&t, NULL); + currentTime = t.tv_sec * 1000 + t.tv_usec / 1000; + } + return NET_Timeout0(s, timeout, currentTime); +} --- old/src/java.base/unix/native/libnet/SocketInputStream.c 2016-09-07 18:50:57.753241551 +0530 +++ new/src/java.base/unix/native/libnet/SocketInputStream.c 2016-09-07 18:50:57.305240796 +0530 @@ -28,14 +28,13 @@ #include #include #include - +#include #include "jvm.h" #include "jni_util.h" #include "net_util.h" #include "java_net_SocketInputStream.h" - /************************************************************************ * SocketInputStream */ @@ -52,6 +51,46 @@ 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 @@ -65,7 +104,7 @@ char BUF[MAX_BUFFER_LEN]; char *bufP; jint fd, nread; - + if (IS_NULL(fdObj)) { /* shouldn't this be a NullPointerException? -br */ JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", @@ -98,32 +137,17 @@ } 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"); - } else { - JNU_ThrowByNameWithMessageAndLastError - (env, JNU_JAVANETPKG "SocketException", "select/poll failed"); - } - } - if (bufP != BUF) { - free(bufP); - } - return -1; + nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout); + } else { + nread = NET_Read(fd, bufP, len); + } + if ((*env)->ExceptionCheck(env)) { + if (bufP != BUF) { + free(bufP); } + return nread; } - - nread = NET_Read(fd, bufP, len); - if (nread <= 0) { if (nread < 0) { @@ -143,7 +167,6 @@ JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", "Operation interrupted"); break; - default: JNU_ThrowByNameWithMessageAndLastError (env, JNU_JAVANETPKG "SocketException", "Read failed"); --- old/src/java.base/unix/native/libnet/net_util_md.h 2016-09-07 18:50:58.981243623 +0530 +++ new/src/java.base/unix/native/libnet/net_util_md.h 2016-09-07 18:50:58.545242887 +0530 @@ -36,6 +36,8 @@ int NET_Timeout(int s, long timeout); int NET_Read(int s, void* buf, size_t len); +int NET_NonBlockingRead(int s, void* buf, size_t len); +int NET_TimeoutWithCurrentTime(int s, long timeout, long currentTime); int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, struct sockaddr *from, socklen_t *fromlen); int NET_ReadV(int s, const struct iovec * vector, int count);