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