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 &gt; 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 &lt; 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);
 }


Reply via email to