Author: mturk
Date: Wed Aug 10 04:37:01 2011
New Revision: 1156019
URL: http://svn.apache.org/viewvc?rev=1156019&view=rev
Log:
Fix socket timeouts and add add hard timeouts if supported by the OS
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketOption.java
commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h
commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c
commons/sandbox/runtime/trunk/src/main/native/os/unix/sockopts.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/sockopts.c
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketOption.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketOption.java?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketOption.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketOption.java
Wed Aug 10 04:37:01 2011
@@ -59,7 +59,30 @@ public enum SocketOption
/**
* Sets timeout on blocking socket operations.
*/
- TIMEOUT( 9);
+ TIMEOUT( 9),
+ /**
+ * Specify the receiving timeouts until reporting an error.
+ * If an input function blocks for this period of time, and data has
+ * been received, the return value of that function will be
+ * the amount of data transferred; if no data has been transferred and
+ * the timeout has been reached then {@code -1} is returned with errno
+ * set to {@code EAGAIN} or {@code EWOULDBLOCK} just as if the socket
+ * was specified to be nonâ blocking. If the timeout is set to
+ * {@code zero} (the default) then the operation will never timeout.
+ */
+ RCVTIMEO( 10),
+ /**
+ * Specify the sending timeouts until reporting an error.
+ * If an output function blocks for this period of time, and data has
+ * been sent, the return value of that function will be
+ * the amount of data transferred; if no data has been transferred and
+ * the timeout has been reached then {@code -1} is returned with errno
+ * set to {@code EAGAIN} or {@code EWOULDBLOCK} just as if the socket
+ * was specified to be non blocking. If the timeout is set to
+ * {@code zero} (the default) then the operation will never timeout.
+ */
+ SNDTIMEO( 11);
+
private int value;
private SocketOption(int v)
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/netdefs.h Wed Aug
10 04:37:01 2011
@@ -80,6 +80,8 @@
#define ACR_OPT_SO_SNDBUF 7
#define ACR_OPT_SO_REUSEADDR 8
#define ACR_OPT_SO_TIMEOUT 9
+#define ACR_OPT_SO_RCVTIMEO 10
+#define ACR_OPT_SO_SNDTIMEO 11
/** Socket options.
* NOTICE: Make sure they are in sync with
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c Wed Aug 10
04:37:01 2011
@@ -247,6 +247,8 @@ ACR_NET_EXPORT(jint, SocketDescriptor, b
#endif
fd->timeout = -1;
ACR_CLRFLAG(fd, ACR_SO_NONBLOCK);
+ ACR_CLRFLAG(fd, ACR_SO_RPART);
+ ACR_CLRFLAG(fd, ACR_SO_WPART);
}
}
else {
@@ -379,6 +381,15 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
ACR_THROW_NET_ERROR(rc);
return 0;
}
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ else {
+ int zero = 0;
+ setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, SSIZEOF(int));
+ setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, SSIZEOF(int));
+ }
+#endif
}
#if O_NONBLOCK_INHERITED
else if (ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
@@ -415,8 +426,7 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
}
else {
ACR_CLRFLAG(sp, ACR_SO_NONBLOCK);
- if (sp->timeout == 0)
- sp->timeout = -1;
+ sp->timeout = -1;
}
switch (aa.sa.sin.sin_family) {
case AF_INET:
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c Wed Aug
10 04:37:01 2011
@@ -186,6 +186,15 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
ACR_THROW_NET_ERROR(rc);
return 0;
}
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ else {
+ int zero = 0;
+ setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, SSIZEOF(int));
+ setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, SSIZEOF(int));
+ }
+#endif
}
#endif
#if defined(DEBUG) || defined(_DEBUG)
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/sockopts.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/sockopts.c?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/sockopts.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/sockopts.c Wed Aug 10
04:37:01 2011
@@ -63,6 +63,10 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
{
int rc = 0;
acr_sd_t *fd = J2P(fp, acr_sd_t *);
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ struct timeval zt = { 0, 0 };
+ struct timeval tv = { val / 1000, (val % 1000) * 1000 };
+#endif
/* Set numeric values */
switch (opt) {
@@ -118,9 +122,9 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
if (fd->timeout != val) {
setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
- (char *)&val, SSIZEOF(int));
+ (char *)&tv, SSIZEOF(struct timeval));
setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
- (char *)&val, SSIZEOF(int));
+ (char *)&tv, SSIZEOF(struct timeval));
}
#endif
}
@@ -130,19 +134,35 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
if ((rc = AcrNonblock(fd->s, 0)) != 0)
return rc;
ACR_CLRFLAG(fd, ACR_SO_NONBLOCK);
+ ACR_CLRFLAG(fd, ACR_SO_RPART);
+ ACR_CLRFLAG(fd, ACR_SO_WPART);
}
#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
- {
- int zero = 0;
- setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
- (char *)&zero, SSIZEOF(int));
- setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
- (char *)&zero, SSIZEOF(int));
- }
+ setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zt, SSIZEOF(struct timeval));
+ setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zt, SSIZEOF(struct timeval));
#endif
}
fd->timeout = val;
break;
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ case ACR_OPT_SO_RCVTIMEO:
+ if (setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&tv, SSIZEOF(struct timeval)) != 0)
+ return ACR_GET_NETOS_ERROR();
+ break;
+ case ACR_OPT_SO_SNDTIMEO:
+ if (setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&tv, SSIZEOF(struct timeval)) != 0)
+ return ACR_GET_NETOS_ERROR();
+ break;
+#else
+ case ACR_OPT_SO_RCVTIMEO:
+ case ACR_OPT_SO_SNDTIMEO:
+ rc = ACR_ENOTIMPL;
+ break;
+#endif
default:
rc = ACR_EINVAL;
break;
@@ -156,6 +176,9 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
int rc = 0;
int on = val == JNI_TRUE ? 1 : 0;
acr_sd_t *fd = J2P(fp, acr_sd_t *);
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ struct timeval zt = { 0, 0 };
+#endif
/* Set numeric values */
switch (opt) {
@@ -182,6 +205,20 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
if ((rc = AcrNonblock(fd->s, on)) != 0)
return rc;
ACR_PUTFLAG(fd, ACR_SO_NONBLOCK, on);
+ if (on) {
+ fd->timeout = 0;
+ }
+ else {
+ fd->timeout = -1;
+ ACR_CLRFLAG(fd, ACR_SO_RPART);
+ ACR_CLRFLAG(fd, ACR_SO_WPART);
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zt, SSIZEOF(struct timeval));
+ setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zt, SSIZEOF(struct timeval));
+#endif
+ }
}
break;
case ACR_OPT_IPV6_V6ONLY:
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c Wed Aug
10 04:37:01 2011
@@ -110,7 +110,7 @@ ACR_NET_EXPORT(jint, SocketDescriptor, b
acr_sd_t *fd = J2P(fp, acr_sd_t *);
if (on == JNI_TRUE) {
- if ((fd->flags & ACR_SO_NONBLOCK) != 0) {
+ if (ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
int zero = 0;
if ((rc = AcrNonblock(fd->s, 0)) != 0)
return rc;
@@ -119,16 +119,18 @@ ACR_NET_EXPORT(jint, SocketDescriptor, b
setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
(char *)&zero, (socklen_t)sizeof(zero));
fd->timeout = -1;
- fd->flags &= ~ACR_SO_NONBLOCK;
+ ACR_CLRFLAG(fd, ACR_SO_NONBLOCK);
+ ACR_CLRFLAG(fd, ACR_SO_RPART);
+ ACR_CLRFLAG(fd, ACR_SO_WPART);
}
}
else {
- if ((fd->flags & ACR_SO_NONBLOCK) == 0) {
+ if (!ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
if ((rc = AcrNonblock(fd->s, 1)) != 0)
return rc;
if (fd->timeout < 0)
fd->timeout = 0;
- fd->flags |= ACR_SO_NONBLOCK;
+ ACR_SETFLAG(fd, ACR_SO_NONBLOCK);
}
}
return 0;
@@ -350,6 +352,7 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
}
}
else if (ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
+ int zero = 0;
/* We have nonblocking acceptor and need
* blocking socket
*/
@@ -359,6 +362,10 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
ACR_THROW_NET_ERROR(rc);
return 0;
}
+ setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
}
if ((sp = ACR_TALLOC(acr_sd_t)) == 0) {
closesocket(sd);
@@ -380,8 +387,7 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
}
else {
ACR_CLRFLAG(sp, ACR_SO_NONBLOCK);
- if (sp->timeout == 0)
- sp->timeout = -1;
+ sp->timeout = -1;
}
switch (aa.sa.sin.sin_family) {
case AF_INET:
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c Wed Aug
10 04:37:01 2011
@@ -229,12 +229,17 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
}
}
else if (ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
+ int zero = 0;
int rc = AcrNonblock(sd, 0);
if (rc != 0) {
closesocket(sd);
ACR_THROW_NET_ERROR(rc);
return 0;
}
+ setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
}
if ((sp = ACR_TALLOC(acr_sd_t)) == 0) {
closesocket(sd);
@@ -252,8 +257,7 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
}
else {
ACR_CLRFLAG(sp, ACR_SO_NONBLOCK);
- if (sp->timeout == 0)
- sp->timeout = -1;
+ sp->timeout = -1;
}
return P2J(sp);
}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/sockopts.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/sockopts.c?rev=1156019&r1=1156018&r2=1156019&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/sockopts.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/sockopts.c Wed Aug
10 04:37:01 2011
@@ -44,7 +44,8 @@ ACR_NET_EXPORT(jboolean, SocketAddress,
ACR_NET_EXPORT(jint, SocketDescriptor, optset0)(JNI_STDARGS, jlong fp,
jint opt, jint val)
{
- int rc = 0;
+ int rc = 0;
+ int zero = 0;
acr_sd_t *fd = J2P(fp, acr_sd_t *);
/* Set numeric values */
@@ -101,17 +102,26 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
if ((rc = AcrNonblock(fd->s, 0)) != 0)
return rc;
ACR_CLRFLAG(fd, ACR_SO_NONBLOCK);
+ ACR_CLRFLAG(fd, ACR_SO_RPART);
+ ACR_CLRFLAG(fd, ACR_SO_WPART);
}
- {
- int zero = 0;
- setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
- (char *)&zero, SSIZEOF(int));
- setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
- (char *)&zero, SSIZEOF(int));
- }
+ setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, SSIZEOF(int));
+ setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, SSIZEOF(int));
}
fd->timeout = val;
break;
+ case ACR_OPT_SO_RCVTIMEO:
+ if (setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&val, SSIZEOF(int)) != 0)
+ return ACR_GET_NETOS_ERROR();
+ break;
+ case ACR_OPT_SO_SNDTIMEO:
+ if (setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&val, SSIZEOF(int)) != 0)
+ return ACR_GET_NETOS_ERROR();
+ break;
default:
rc = ACR_EINVAL;
break;
@@ -122,6 +132,7 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
ACR_NET_EXPORT(jint, SocketDescriptor, optset1)(JNI_STDARGS, jlong fp,
jint opt, jboolean val)
{
+ int zero = 0;
int rc = 0;
int on = val == JNI_TRUE ? 1 : 0;
acr_sd_t *fd = J2P(fp, acr_sd_t *);
@@ -147,6 +158,18 @@ ACR_NET_EXPORT(jint, SocketDescriptor, o
if ((rc = AcrNonblock(fd->s, on)) != 0)
return rc;
ACR_PUTFLAG(fd, ACR_SO_NONBLOCK, on);
+ if (on) {
+ fd->timeout = 0;
+ }
+ else {
+ fd->timeout = -1;
+ ACR_CLRFLAG(fd, ACR_SO_RPART);
+ ACR_CLRFLAG(fd, ACR_SO_WPART);
+ setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, SSIZEOF(int));
+ setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, SSIZEOF(int));
+ }
}
break;
default: