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