< prev index next >
src/java.base/unix/native/libnet/SocketInputStream.c
Print this page
*** 26,43 ****
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
!
#include "jvm.h"
#include "jni_util.h"
#include "net_util.h"
#include "java_net_SocketInputStream.h"
-
/************************************************************************
* SocketInputStream
*/
static jfieldID IO_fd_fdID;
--- 26,42 ----
#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,59 ****
--- 49,120 ----
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_TimeoutWithCurrentTime(int s, long timeout, long current_time) {
+ int result;
+ long prevtime = current_time, newtime;
+ struct pollfd pfd;
+ pfd.fd = s;
+ pfd.events = POLLIN;
+ for (;;) {
+ result = poll(&pfd, 1, timeout);
+ if (result < 0 && errno == EINTR) {
+ if (timeout > 0) {
+ newtime = getCurrentTime();
+ timeout -= newtime - prevtime;
+ if (timeout <= 0)
+ return 0;
+ prevtime = newtime;
+ }
+ } else {
+ return result;
+ }
+ }
+ }
+
+ static int NET_ReadWithTimeout(JNIEnv *env, int fd, char *bufP, int len, long timeout) {
+ int result;
+ 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,131 ****
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");
} else {
- JNU_ThrowByNameWithMessageAndLastError
- (env, JNU_JAVANETPKG "SocketException", "select/poll failed");
- }
- }
- if (bufP != BUF) {
- free(bufP);
- }
- return -1;
- }
- }
-
nread = NET_Read(fd, bufP, len);
!
if (nread <= 0) {
if (nread < 0) {
switch (errno) {
case ECONNRESET:
--- 157,171 ----
len = MAX_BUFFER_LEN;
}
} else {
bufP = BUF;
}
if (timeout) {
! nread = NET_ReadWithTimeout(env, fd, bufP, len, timeout);
} else {
nread = NET_Read(fd, bufP, len);
! }
if (nread <= 0) {
if (nread < 0) {
switch (errno) {
case ECONNRESET:
*** 141,151 ****
case EINTR:
JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
"Operation interrupted");
break;
-
default:
JNU_ThrowByNameWithMessageAndLastError
(env, JNU_JAVANETPKG "SocketException", "Read failed");
}
}
--- 181,190 ----
< prev index next >