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