Author: mturk
Date: Wed Jul 13 09:30:38 2011
New Revision: 1145929
URL: http://svn.apache.org/viewvc?rev=1145929&view=rev
Log:
Add setter for socket timeout
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Endpoint.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpoint.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalServerEndpoint.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
commons/sandbox/runtime/trunk/src/main/native/configure
commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.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/sockstream.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw
commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Endpoint.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Endpoint.java?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Endpoint.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/Endpoint.java
Wed Jul 13 09:30:38 2011
@@ -215,5 +215,22 @@ public abstract class Endpoint implement
return register(selector, 0, null);
}
+ /**
+ * Setup timeout in milliseconds for the specified endpoint.
+ *
+ * <pre>
+ * t > 0 -- read and write calls throws TimeoutException if specified
+ * time elapsess with no data read or written
+ * t == 0 -- read and write calls never block
+ * t < 0 -- read and write calls block
+ *
+ * </pre>
+ * @param timeout
+ * timeout value in milliseconds.
+ * @throws SocketException
+ * if an error occurs while setting the option.
+ */
+ public abstract void setTimeout(int timeout)
+ throws IOException;
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
Wed Jul 13 09:30:38 2011
@@ -41,6 +41,7 @@ final class LocalDescriptor extends Desc
private static native long socket0(int type, boolean blocking)
throws IOException;
private static native int block0(long fd, boolean block);
+ private static native int tmset0(long fd, int timeout);
private static native boolean isBlocking0(long fd)
throws IOException;
@@ -119,4 +120,14 @@ final class LocalDescriptor extends Desc
throw new ClosedDescriptorException();
}
+ public void setTimeout(int timeout)
+ throws IOException
+ {
+ if (closed())
+ throw new ClosedDescriptorException();
+ int rc = tmset0(fd, timeout);
+ if (rc != 0)
+ throw new SocketException(Status.describe(rc));
+ }
+
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpoint.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpoint.java?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpoint.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalEndpoint.java
Wed Jul 13 09:30:38 2011
@@ -178,4 +178,11 @@ public class LocalEndpoint extends Endpo
return key.queue(ops & 0x000f);
}
+ @Override
+ public void setTimeout(int timeout)
+ throws IOException
+ {
+ sd.setTimeout(timeout);
+ }
+
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalServerEndpoint.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalServerEndpoint.java?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalServerEndpoint.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalServerEndpoint.java
Wed Jul 13 09:30:38 2011
@@ -187,4 +187,16 @@ public class LocalServerEndpoint extends
LocalDescriptor ad = new LocalDescriptor(fd);
return new LocalEndpoint(ad, sa);
}
+
+ @Override
+ public void setTimeout(int timeout)
+ throws IOException
+ {
+ sd.setTimeout(timeout);
+ if (timeout < 0)
+ blocking = true;
+ else
+ blocking = false;
+ }
+
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
Wed Jul 13 09:30:38 2011
@@ -38,6 +38,7 @@ final class SocketDescriptor extends Des
private static native long socket0(int af, int type, boolean blocking)
throws IOException;
private static native int block0(long fd, boolean block);
+ private static native int tmset0(long fd, int timeout);
private static native boolean isBlocking0(long fd)
throws IOException;
@@ -116,4 +117,14 @@ final class SocketDescriptor extends Des
throw new ClosedDescriptorException();
}
+ public void setTimeout(int timeout)
+ throws IOException
+ {
+ if (closed())
+ throw new ClosedDescriptorException();
+ int rc = tmset0(fd, timeout);
+ if (rc != 0)
+ throw new SocketException(Status.describe(rc));
+ }
+
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketEndpoint.java
Wed Jul 13 09:30:38 2011
@@ -157,4 +157,11 @@ public class SocketEndpoint extends Endp
return key.queue(ops & 0x000f);
}
+ @Override
+ public void setTimeout(int timeout)
+ throws IOException
+ {
+ sd.setTimeout(timeout);
+ }
+
}
Modified: commons/sandbox/runtime/trunk/src/main/native/configure
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/configure?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/configure (original)
+++ commons/sandbox/runtime/trunk/src/main/native/configure Wed Jul 13 09:30:38
2011
@@ -1088,6 +1088,33 @@ EOF
echo $rc
}
+have_sockopt()
+{
+ do_printf 'Checking for %-32s' "$1"
+ cat > $cccsrc.c << EOF
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+int rc = 0;
+int main () {
+#ifdef $1
+ int s;
+ struct timeval tv = { 3, 0 };
+ if ((s = socket(AF_INET, SOCK_STREAM, 0)) != -1)
+ if (setsockopt(s, SOL_SOCKET, $1, (const void *)&tv, sizeof(tv)) != -1)
+ rc = 1;
+#endif
+ printf("%d", rc);
+ return 0;
+}
+EOF
+ rc=`test_compile z 0`
+ echo $rc
+}
+
have_working_getnameinfo()
{
do_printf 'Checking for %-32s' "working getnameinfo"
@@ -1491,6 +1518,8 @@ extern "C" {
#define HAVE_POSIX_SEMAPHORE $have_posixsem
#define HAVE_THREAD_LOCAL `have_thread_local`
#define HAVE_IPV6 `have_socket AF_INET6 SOCK_STREAM 'ipv6
support'`
+#define HAVE_SO_RCVTIMEO `have_sockopt SO_RCVTIMEO`
+#define HAVE_SO_SNDTIMEO `have_sockopt SO_SNDTIMEO`
#define HAVE_OPENSSL $have_openssl
#define HAVE_OPENSSL_STATIC $have_openssl_static
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h Wed
Jul 13 09:30:38 2011
@@ -19,16 +19,25 @@
#include "acr/jniapi.h"
-#define ACR_DT_NBLOCK 0x0001
-#define ACR_DT_MASK 0xfff0
-#define ACR_DT_SOCKET 0x0010
-#define ACR_DT_LSOCK 0x0020
-#define ACR_DT_PIPE 0x0040
+/**
+ * Descriptor flags
+ */
+#define ACR_DT_NONBLOCK 0x0001
+
+/**
+ * Descriptor types
+ */
+#define ACR_DT_FILE 0x0001
+#define ACR_DT_SOCKET 0x0002
+#define ACR_DT_LSOCK 0x0003
+#define ACR_DT_PIPE 0x0004
typedef struct acr_fd_t acr_fd_t;
struct acr_fd_t {
- int type; /**< Descriptor type */
- volatile acr_atomic32_t refs; /**< Reference counter */
+ volatile acr_atomic32_t refs; /**< Reference counter */
+ int type; /**< Descriptor type */
+ int timeout;
+ int flags;
union {
jlong nh;
void *p;
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=1145929&r1=1145928&r2=1145929&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 Jul 13
09:30:38 2011
@@ -86,8 +86,14 @@ ACR_NET_EXPORT(jlong, SocketDescriptor,
r_close(sd);
return 0;
}
- sp->refs = 1;
- sp->u.s = sd;
+ sp->type = ACR_DT_SOCKET;
+ sp->timeout = -1;
+ sp->refs = 1;
+ sp->u.s = sd;
+ if (block == JNI_FALSE) {
+ sp->flags = ACR_DT_NONBLOCK;
+ sp->timeout = 0;
+ }
return P2J(sp);
}
@@ -121,30 +127,44 @@ ACR_NET_EXPORT(jint, SocketDescriptor, s
ACR_NET_EXPORT(jint, SocketDescriptor, block0)(JNI_STDARGS, jlong fp, jboolean
on)
{
- acr_fd_t *fd = J2P(fp, acr_fd_t *);
- return AcrNonblock(fd->u.s, on == JNI_FALSE);
+ int rc = 0;
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
+
+ if (on == JNI_TRUE) {
+ if ((fd->flags & ACR_DT_NONBLOCK) != 0 &&
+ (rc = AcrNonblock(fd->u.s, 0)) == 0) {
+ fd->timeout = -1;
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ {
+ int zero = 0;
+ setsockopt(fd->u.s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(fd->u.s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ }
+#endif
+ fd->flags &= ~ACR_DT_NONBLOCK;
+ }
+ }
+ else {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0 &&
+ (rc = AcrNonblock(fd->u.s, 1)) == 0) {
+ if (fd->timeout < 0)
+ fd->timeout = 0;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ }
+ return rc;
}
ACR_NET_EXPORT(jboolean, SocketDescriptor, isBlocking0)(JNI_STDARGS, jlong fp)
{
-#ifdef O_NONBLOCK
- /* Use non-blocking I/O
- */
- long mode;
- acr_fd_t *fd = J2P(fp, acr_fd_t *);
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
- if ((mode = fcntl(fd->u.s, F_GETFL, 0)) == -1) {
- ACR_THROW_NET_ERRNO();
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0)
return JNI_TRUE;
- }
- if ((mode & O_NONBLOCK) == O_NONBLOCK)
+ else
return JNI_FALSE;
-#else
- /* Non blocking I/O is unsupported.
- */
- ACR_THROW_NET_ERROR(ACR_ENOTIMPL);
-#endif
- return JNI_TRUE;
}
ACR_NET_EXPORT(jboolean, SocketAddress, haveipv6)(JNI_STDARGS)
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=1145929&r1=1145928&r2=1145929&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 Jul
13 09:30:38 2011
@@ -86,6 +86,7 @@ ACR_NET_EXPORT(jlong, LocalDescriptor, s
int sd;
int rc = 0;
int type = 0;
+
acr_fd_t *sp;
switch (stype) {
@@ -130,20 +131,105 @@ ACR_NET_EXPORT(jlong, LocalDescriptor, s
r_close(sd);
return 0;
}
- sp->type = ACR_DT_LSOCK;
- sp->refs = 1;
- sp->u.s = sd;
+ sp->type = ACR_DT_LSOCK;
+ sp->timeout = -1;
+ sp->refs = 1;
+ sp->u.s = sd;
+ if (block == JNI_FALSE) {
+ sp->flags = ACR_DT_NONBLOCK;
+ sp->timeout = 0;
+ }
return P2J(sp);
}
ACR_NET_EXPORT(jint, LocalDescriptor, block0)(JNI_STDARGS, jlong fp, jboolean
on)
{
+ int rc = 0;
acr_fd_t *fd = J2P(fp, acr_fd_t *);
- return AcrNonblock(fd->u.s, on == JNI_FALSE);
+
+ if (on == JNI_TRUE) {
+ if ((fd->flags & ACR_DT_NONBLOCK) != 0 &&
+ (rc = AcrNonblock(fd->u.s, 0)) == 0) {
+ fd->timeout = -1;
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ {
+ int zero = 0;
+ setsockopt(fd->u.s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(fd->u.s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ }
+#endif
+ fd->flags &= ~ACR_DT_NONBLOCK;
+ }
+ }
+ else {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0 &&
+ (rc = AcrNonblock(fd->u.s, 1)) == 0) {
+ if (fd->timeout < 0)
+ fd->timeout = 0;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ }
+ return rc;
+}
+
+ACR_NET_EXPORT(jint, LocalDescriptor, tmset0)(JNI_STDARGS, jlong fp, jint
timeout)
+{
+ int rc;
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
+
+ if (timeout == 0) {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->u.s, 1)) != 0)
+ return rc;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ }
+ else if (timeout > 0) {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->u.s, 1)) != 0)
+ return rc;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ if (fd->timeout != timeout) {
+ setsockopt(fd->u.s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&timeout, (socklen_t)sizeof(timeout));
+ setsockopt(fd->u.s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&timeout, (socklen_t)sizeof(timeout));
+ }
+#endif
+ }
+ else if (timeout < 0) {
+ if ((fd->flags & ACR_DT_NONBLOCK) != 0) {
+ if ((rc = AcrNonblock(fd->u.s, 0)) != 0)
+ return rc;
+ fd->flags &= ~ACR_DT_NONBLOCK;
+ }
+#if HAVE_SO_RCVTIMEO && HAVE_SO_SNDTIMEO
+ {
+ int zero = 0;
+ setsockopt(fd->u.s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(fd->u.s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ }
+#endif
+ }
+ fd->timeout = timeout;
+ return 0;
}
ACR_NET_EXPORT(jboolean, LocalDescriptor, isBlocking0)(JNI_STDARGS, jlong fp)
{
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
+
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+#if 0
#ifdef O_NONBLOCK
/* Use non-blocking I/O
*/
@@ -162,6 +248,7 @@ ACR_NET_EXPORT(jboolean, LocalDescriptor
ACR_THROW_NET_ERROR(ACR_ENOTIMPL);
#endif
return JNI_TRUE;
+#endif
}
ACR_NET_EXPORT(jint, LocalEndpoint, connect0)(JNI_STDARGS, jlong fp,
@@ -171,6 +258,14 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
acr_sockaddr_t *ca = SOCKADDR_CAST(cb);
acr_fd_t *fd = J2P(fp, acr_fd_t *);
+ if (timeout == 0)
+ timeout = fd->timeout;
+ if (timeout > 0 && (fd->flags & ACR_DT_NONBLOCK) == 0) {
+ /* Turn the socket to non-blocking mode
+ */
+ if ((rc = AcrNonblock(fd->u.s, 1)) != 0)
+ return rc;
+ }
do {
/* Restartable connect */
rc = connect(fd->u.s, (const struct sockaddr *)&ca->sa.sin, ca->salen);
@@ -180,18 +275,22 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
rc = errno;
SOCKADDR_RELEASE(cb, ca);
if (rc != 0) {
- if (timeout > 0 && (rc == EINPROGRESS || rc == EALREADY)) {
- rc = AcrWaitIO(fd->u.s, timeout, POLLOUT);
+ if (timeout > 0) {
+ if (rc == EINPROGRESS || rc == EALREADY) {
+ rc = AcrWaitIO(fd->u.s, timeout, POLLOUT);
#if defined(SO_ERROR)
- if (rc == 0) {
- int err;
- socklen_t len = sizeof(err);
- if (getsockopt(fd->u.s, SOL_SOCKET, SO_ERROR, (char *)&err,
&len) == -1);
- rc = errno;
- if (err != 0)
- rc = err;
- }
+ if (rc == 0) {
+ int err;
+ socklen_t len = sizeof(err);
+ if (getsockopt(fd->u.s, SOL_SOCKET, SO_ERROR, (char
*)&err, &len) == -1);
+ rc = errno;
+ if (err != 0)
+ rc = err;
+ }
#endif
+ }
+ if ((fd->type & ACR_DT_NONBLOCK) == 0)
+ AcrNonblock(fd->u.s, 0);
}
}
return rc;
@@ -233,12 +332,13 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
socklen_t aalen;
acr_fd_t *fd = J2P(fp, acr_fd_t *);
acr_fd_t *sp;
+
#if HAVE_ACCEPT4
int flags = SOCK_CLOEXEC;
-#endif
-#if HAVE_NONBLOCK_INHERITED
+# if HAVE_NONBLOCK_INHERITED
if (block == JNI_FALSE)
flags |= SOCK_NONBLOCK;
+# endif
#endif
memset(&aa, 0, sizeof(aa));
@@ -285,8 +385,15 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
r_close(sd);
return 0;
}
- sp->type = ACR_DT_LSOCK;
- sp->refs = 1;
- sp->u.s = sd;
+ sp->type = ACR_DT_LSOCK;
+ sp->flags = fd->flags;
+ sp->timeout = fd->timeout;
+ sp->refs = 1;
+ sp->u.s = sd;
+ if (block == JNI_FALSE) {
+ sp->flags |= ACR_DT_NONBLOCK;
+ if (sp->timeout < 0)
+ sp->timeout = 0;
+ }
return P2J(sp);
}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/sockstream.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/sockstream.c?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/sockstream.c
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/sockstream.c Wed Jul
13 09:30:38 2011
@@ -23,6 +23,7 @@
#include "acr/netapi.h"
#include "acr/unsafe.h"
#include "acr/port.h"
+#include "acr/time.h"
#include "arch_opts.h"
#include "arch_sync.h"
#include <poll.h>
@@ -49,6 +50,11 @@ ACR_INLINE(int) _retain_sd(acr_ss_t *ss)
ACR_INLINE(void) _release_sd(acr_ss_t *ss)
{
if (AcrAtomic32Dec(&ss->fd->refs) == 0) {
+ /* Socket was closed while we were
+ * executing the native method.
+ * Since Socket didn't free the fd
+ * we have to do it here.
+ */
AcrFree(ss->fd);
ss->fd = 0;
}
@@ -93,11 +99,16 @@ ACR_NET_EXPORT(jint, SocketStream, read0
goto finally;
}
rd = r_read(sd, &ch, 1);
+ if (rd == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) &&
+ ss->fd->timeout > 0) {
+ rc = AcrWaitIO(sd, AcrTimeAsMsec(ss->fd->timeout), POLLOUT);
+ if (rc != 0)
+ goto finally;
+ rd = r_read(sd, &ch, 1);
+ }
if (rd == -1)
rc = ACR_GET_OS_ERROR();
- else if (rd == 0)
- rv = -1;
- else
+ else if (rd != 0)
rv = ch;
finally:
_release_sd(ss);
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw?rev=1145929&r1=1145928&r2=1145929&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/config.hw Wed Jul 13
09:30:38 2011
@@ -141,6 +141,8 @@
#define HAVE_FUNC 0
#define HAVE_FUNCSIG 1
#define HAVE_THREAD_LOCAL 1
+#define HAVE_SO_RCVTIMEO 1
+#define HAVE_SO_SNDTIMEO 1
#define HAVE_OCSP 0
#define HAVE_KSTAT 0
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=1145929&r1=1145928&r2=1145929&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 Jul
13 09:30:38 2011
@@ -101,7 +101,6 @@ ACR_NET_EXPORT(jlong, LocalDescriptor, s
SOCKET sd;
int rc = 0;
int type = 0;
- int desc = ACR_DT_LSOCK;
wls_fd_t *sp;
switch (stype) {
@@ -125,7 +124,6 @@ ACR_NET_EXPORT(jlong, LocalDescriptor, s
rc = ACR_GET_NETOS_ERROR();
closesocket(sd);
}
- desc |= ACR_DT_NBLOCK;
}
if (rc != 0) {
ACR_THROW_NET_ERROR(rc);
@@ -135,31 +133,97 @@ ACR_NET_EXPORT(jlong, LocalDescriptor, s
closesocket(sd);
return 0;
}
- sp->fd.type = desc;
- sp->fd.refs = 1;
- sp->fd.u.s = sd;
- sp->fh = 0;
+ sp->fd.type = ACR_DT_LSOCK;
+ sp->fd.timeout = -1;
+ sp->fd.refs = 1;
+ sp->fd.u.s = sd;
+ sp->fh = 0;
+ if (block == JNI_FALSE) {
+ sp->fd.flags |= ACR_DT_NONBLOCK;
+ sp->fd.timeout = 0;
+ }
return P2J(sp);
}
ACR_NET_EXPORT(jint, LocalDescriptor, block0)(JNI_STDARGS, jlong fp, jboolean
on)
{
+ int rc;
acr_fd_t *fd = J2P(fp, acr_fd_t *);
- u_long set = (u_long)on;
- if (ioctlsocket(fd->u.s, FIONBIO, &set) == SOCKET_ERROR)
- return ACR_GET_NETOS_ERROR();
- if (on)
- fd->type |= ACR_DT_NBLOCK;
- else
- fd->type &= ~ACR_DT_NBLOCK;
+ if (on == JNI_TRUE) {
+ if ((fd->flags & ACR_DT_NONBLOCK) != 0) {
+ int zero = 0;
+ if ((rc = AcrNonblock(fd->u.s, 0)) != 0)
+ return rc;
+ setsockopt(fd->u.s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(fd->u.s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ fd->timeout = -1;
+ fd->flags &= ~ACR_DT_NONBLOCK;
+ }
+ }
+ else {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->u.s, 1)) != 0)
+ return rc;
+ if (fd->timeout < 0)
+ fd->timeout = 0;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ }
return 0;
}
ACR_NET_EXPORT(jboolean, LocalDescriptor, isBlocking0)(JNI_STDARGS, jlong fp)
{
acr_fd_t *fd = J2P(fp, acr_fd_t *);
- return (fd->type & ACR_DT_NBLOCK) == ACR_DT_NBLOCK ? JNI_FALSE : JNI_TRUE;
+
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0)
+ return JNI_TRUE;
+ else
+ return JNI_FALSE;
+}
+
+ACR_NET_EXPORT(jint, LocalDescriptor, tmset0)(JNI_STDARGS, jlong fp, jint
timeout)
+{
+ int rc = 0;
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
+
+ if (timeout == 0) {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->u.s, 1)) != 0)
+ return rc;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ }
+ else if (timeout > 0) {
+ if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+ if ((rc = AcrNonblock(fd->u.s, 1)) != 0)
+ return rc;
+ fd->flags |= ACR_DT_NONBLOCK;
+ }
+ if (fd->timeout != timeout) {
+ setsockopt(fd->u.s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&timeout, (socklen_t)sizeof(timeout));
+ setsockopt(fd->u.s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&timeout, (socklen_t)sizeof(timeout));
+ }
+ }
+ else if (timeout < 0) {
+ int zero = 0;
+ if ((fd->flags & ACR_DT_NONBLOCK) != 0) {
+ if ((rc = AcrNonblock(fd->u.s, 0)) != 0)
+ return rc;
+ fd->flags &= ~ACR_DT_NONBLOCK;
+ }
+ setsockopt(fd->u.s, SOL_SOCKET, SO_RCVTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ setsockopt(fd->u.s, SOL_SOCKET, SO_SNDTIMEO,
+ (char *)&zero, (socklen_t)sizeof(zero));
+ }
+ fd->timeout = timeout;
+ return 0;
}
ACR_NET_EXPORT(jint, LocalEndpoint, connect0)(JNI_STDARGS, jlong fp,
@@ -315,7 +379,6 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
ACR_THROW_NET_ERRNO();
return 0;
}
- type = wd->fd.type;
if (block == JNI_FALSE && (type & ACR_DT_NBLOCK) == 0) {
int rc = AcrNonblock(sd, 1);
if (rc != 0) {
@@ -323,8 +386,9 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
ACR_THROW_NET_ERROR(rc);
return 0;
}
- type |= ACR_DT_NBLOCK;
}
+ else
+ block = JNI_TRUE;
if ((sp = ACR_TALLOC(wls_fd_t)) == 0) {
closesocket(sd);
return 0;
@@ -336,8 +400,17 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
aa->port = ntohs(sa.sin_port);
}
SOCKADDR_RELEASE(ba, aa);
- sp->fd.type = type;
- sp->fd.refs = 1;
- sp->fd.u.s = sd;
+
+ sp->fd.type = ACR_DT_LSOCK;
+ sp->fd.flags = wd->fd.flags
+ sp->fd.timeout = wd->fd.timeout;
+ sp->fd.refs = 1;
+ sp->fd.u.s = sd;
+ sp->fh = 0;
+ if (block == JNI_FALSE) {
+ sp->fd.flags |= ACR_DT_NONBLOCK;
+ if (sp->fd.timeout < 0)
+ sp->fd.timeout = 0;
+ }
return P2J(sp);
}