Author: mturk
Date: Mon Jul 18 04:51:11 2011
New Revision: 1147743
URL: http://svn.apache.org/viewvc?rev=1147743&view=rev
Log:
Implement methods and test for SocketEndpoint
Added:
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestLocalEndpoint.java
- copied, changed from r1147618,
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestPosixEndpoint.java
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestServerEndpoint.java
(with props)
Removed:
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestPosixEndpoint.java
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Reader.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Writer.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/SocketAddress.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/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
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/win32/localsock.c
commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Reader.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Reader.java?rev=1147743&r1=1147742&r2=1147743&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Reader.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Reader.java
Mon Jul 18 04:51:11 2011
@@ -20,6 +20,7 @@ package org.apache.commons.runtime.io;
import java.io.IOException;
import java.nio.ByteBuffer;
+import org.apache.commons.runtime.DirectByteBuffer;
import org.apache.commons.runtime.Pointer;
/**
@@ -191,7 +192,7 @@ public interface Reader
* blocking mode.
* <p>
* {@code ByteBuffer} must be allocated using {@code allocatedirect()}
- * or obtained from {@link NioByteBuffer}.
+ * or obtained from {@link DirectByteBuffer}.
* </p>
*
* @param buffer
@@ -220,7 +221,7 @@ public interface Reader
* is reached or an exception is thrown.
* <p>
* {@code ByteBuffer} must be allocated using {@code allocatedirect()}
- * or obtained from {@link NioByteBuffer}.
+ * or obtained from {@link DirectByteBuffer}.
* </p>
*
* @param buffer
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Writer.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Writer.java?rev=1147743&r1=1147742&r2=1147743&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Writer.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Writer.java
Mon Jul 18 04:51:11 2011
@@ -20,6 +20,7 @@ package org.apache.commons.runtime.io;
import java.io.IOException;
import java.nio.ByteBuffer;
+import org.apache.commons.runtime.DirectByteBuffer;
import org.apache.commons.runtime.Pointer;
/**
@@ -166,7 +167,7 @@ public interface Writer extends Syncable
* to this stream, starting at the current stream position.
* <p>
* {@code ByteBuffer} must be allocated using {@code allocatedirect()}
- * or obtained from {@link NioByteBuffer}.
+ * or obtained from {@link DirectByteBuffer}.
* </p>
*
* @param buffer
@@ -193,7 +194,7 @@ public interface Writer extends Syncable
* to get bytes.
* <p>
* {@code ByteBuffer} must be allocated using {@code allocatedirect()}
- * or obtained from {@link NioByteBuffer}.
+ * or obtained from {@link DirectByteBuffer}.
* </p>
*
* @param buffer
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=1147743&r1=1147742&r2=1147743&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
Mon Jul 18 04:51:11 2011
@@ -61,12 +61,12 @@ public class LocalServerEndpoint extends
* Creates a new local server endpoint from the
* given socket descriptor.
*/
- public LocalServerEndpoint(SocketDescriptor sd)
+ public LocalServerEndpoint(Descriptor sd)
{
super(EndpointType.LOCAL);
if (sd == null)
throw new NullPointerException();
- this.sd = sd;
+ this.sd = (SocketDescriptor)sd;
}
@Override
@@ -157,7 +157,7 @@ public class LocalServerEndpoint extends
}
private static native int bind0(long fd, byte[] sa, int backlog);
- private static native long accept0(long fd, byte[] sa, boolean
block)
+ private static native long accept0(long fd, boolean block)
throws SocketException;
@Override
@@ -196,7 +196,7 @@ public class LocalServerEndpoint extends
{
if (sd.closed())
throw new ClosedDescriptorException();
- long fd = accept0(sd.fd(), sa.sockaddr(), blocking);
+ long fd = accept0(sd.fd(), blocking);
SocketDescriptor ad = new SocketDescriptor(fd);
return new LocalEndpoint(ad, sa);
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java?rev=1147743&r1=1147742&r2=1147743&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketAddress.java
Mon Jul 18 04:51:11 2011
@@ -26,8 +26,9 @@ import org.apache.commons.runtime.Status
import org.apache.commons.runtime.InvalidArgumentException;
/**
- * This class represents a socket endpoint described by a IP address and a port
- * number. It is a concrete implementation of {@code java.net.SocketAddress}
for IP.
+ * This class represents a socket endpoint described by a IP address
+ * and a port number.
+ * It is a concrete implementation of {@code EndpointAddress} for IP.
*/
public abstract class SocketAddress extends EndpointAddress
{
@@ -55,14 +56,16 @@ public abstract class SocketAddress exte
}
/**
- * Creates an new object
+ * Creates a new object.
+ *
*/
protected SocketAddress()
{
}
/**
- * Creates an new object
+ * Creates a new object.
+ *
* @param family indicates a protocl family accepted.
*/
protected SocketAddress(AddressFamily family)
@@ -82,7 +85,8 @@ public abstract class SocketAddress exte
}
/**
- * Creates an new object
+ * Creates a new object.
+ *
* @param family indicates a protocl family accepted.
* @param sockaddr binary socket address.
*/
@@ -93,7 +97,7 @@ public abstract class SocketAddress exte
}
/**
- * Gets the hostname of this socket.
+ * Gets the hostname of this address.
* <p>
* The methods does not resolve the host name. If the address was
* not resloved already the method returns IP notion of the address.
@@ -120,9 +124,9 @@ public abstract class SocketAddress exte
}
/**
- * Gets the service name of this socket.
+ * Gets the service name for this address.
*
- * @return the socket endpoint service name.
+ * @return the service name.
*/
public final String getServiceName()
{
@@ -130,15 +134,20 @@ public abstract class SocketAddress exte
}
/**
- * Gets the port number of this socket.
+ * Gets the port number of this address.
*
- * @return the socket endpoint port number.
+ * @return the port number.
*/
public final int getPort()
{
return port0(super.sa);
}
+ /**
+ * Gets the string IP representation of this address.
+ *
+ * @return IP address string.
+ */
public final String getIpAddress()
{
return ipaddr0(super.sa);
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=1147743&r1=1147742&r2=1147743&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
Mon Jul 18 04:51:11 2011
@@ -68,8 +68,10 @@ final class SocketDescriptor extends Des
public void create(AddressFamily af, SocketType type, boolean blocking)
throws IOException
{
- this.fd = socket0(af.valueOf(), type.valueOf(), blocking);
- closed = false;
+ if (valid())
+ close0(fd);
+ fd = socket0(af.valueOf(), type.valueOf(), blocking);
+ closed = false;
}
public void create(SocketType type)
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=1147743&r1=1147742&r2=1147743&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
Mon Jul 18 04:51:11 2011
@@ -25,9 +25,13 @@ import java.io.SyncFailedException;
import java.net.SocketException;
import org.apache.commons.runtime.io.ClosedDescriptorException;
import org.apache.commons.runtime.io.Descriptor;
+import org.apache.commons.runtime.io.OperationInProgressException;
+import org.apache.commons.runtime.io.OperationWouldBlockException;
import org.apache.commons.runtime.io.Stream;
-import org.apache.commons.runtime.OverflowException;
+import org.apache.commons.runtime.Errno;
import org.apache.commons.runtime.Status;
+import org.apache.commons.runtime.OverflowException;
+import org.apache.commons.runtime.TimeoutException;
/**
* This class represents a socket endpoint.
@@ -40,6 +44,7 @@ public class SocketEndpoint extends Conn
private SocketAddress sa = null; // Local address
private SocketStream stream = null;
private boolean connected = false;
+ private static native int connect0(long fd, byte[] sa, int
timeout);
/**
* Creates a new unconnected socket endpoint.
@@ -52,15 +57,16 @@ public class SocketEndpoint extends Conn
/**
* Creates a new connected socket endpoint from a socket descriptor
- * and remote address.
+ * and remote and local address.
*/
- public SocketEndpoint(Descriptor sd, SocketAddress ea)
+ public SocketEndpoint(Descriptor sd, SocketAddress remote, SocketAddress
local)
{
super(EndpointType.SOCKET);
- if (sd == null || ea == null)
+ if (sd == null || remote == null)
throw new NullPointerException();
this.sd = (SocketDescriptor)sd;
- this.ea = ea;
+ this.ea = remote;
+ this.sa = local;
connected = true;
}
@@ -77,6 +83,18 @@ public class SocketEndpoint extends Conn
sd.create(sockaddr.getFamily(), SocketType.STREAM);
if (Address.resolved(sockaddr))
ea = sockaddr;
+ int rc = connect0(sd.fd(), sockaddr.sockaddr(), timeout);
+ if (rc != 0) {
+ // XXX: Should exception throwing go inside native?
+ if (Status.IS_TIMEUP(rc))
+ throw new TimeoutException();
+ else if (Status.IS_EAGAIN(rc))
+ throw new OperationWouldBlockException();
+ else if (Status.IS_EINPROGRESS(rc))
+ throw new OperationInProgressException();
+ else
+ throw new IOException(Status.describe(rc));
+ }
connected = true;
}
@@ -205,34 +223,75 @@ public class SocketEndpoint extends Conn
return connected;
}
+ /**
+ * Gets the local address this socket is bound to.
+ *
+ * @return the local address of this socket or {@code null} if
+ * the socket is unbound.
+ * @throws IOException if there was an error when resolving
+ * the local address.
+ */
public synchronized SocketAddress getLocalAddress()
throws IOException
{
- if (closed())
- throw new ClosedDescriptorException();
- if (ea != null)
- return ea;
- ea = new AbstractSocketAddress(sd.getLocalAddress());
+ if (connected) {
+ if (ea != null)
+ return ea;
+ ea = new AbstractSocketAddress(sd.getLocalAddress());
+ }
return ea;
}
+ /**
+ * Gets the remote address of this socket or {@code null} if
+ * the socket is not connected.
+ *
+ * @return the remote address of this socket or {@code null} if
+ * the socket is not connected.
+ * @throws IOException if there was an error when resolving
+ * the remote address.
+ */
public synchronized SocketAddress getRemoteAddress()
throws IOException
{
- if (closed())
- throw new ClosedDescriptorException();
+ if (!connected)
+ return null;
if (sa != null)
return sa;
sa = new AbstractSocketAddress(sd.getRemoteAddress());
return sa;
}
+ /**
+ * Returns the {@code SocketOption} state of the socket.
+ *
+ * @param key the {@code SocketOption} to check.
+ * @return {@code true} if the socket has the requested
+ * option set.
+ * @throws OperationNotImplededException
+ * if the socket does not support this option.
+ * @throws IOException if there was an error when querying
+ * the socket option.
+ * @see SocketOption
+ */
public boolean hasOption(SocketOption key)
throws IOException
{
return sd.hasOption(key);
}
+ /**
+ * Returns the {@code TcpOption} state of the socket.
+ *
+ * @param key the {@code TcpOption} to check.
+ * @return {@code true} if the socket has the requested
+ * option set.
+ * @throws OperationNotImplededException
+ * if the socket does not support this option.
+ * @throws IOException if there was an error when querying
+ * the socket option.
+ * @see TcpOption
+ */
public boolean hasOption(TcpOption key)
throws IOException
{
@@ -241,22 +300,64 @@ public class SocketEndpoint extends Conn
return sd.hasOption(key);
}
+ /**
+ * Sets the value of the {@code SocketOption} for this socket.
+ *
+ * @param key the {@code SocketOption} to set.
+ * @param val the value to set.
+ *
+ * @throws InvalidArgumentException
+ * if the socket does not support setting numerical values.
+ * @throws OperationNotImplededException
+ * if the socket does not support this option.
+ * @throws IOException if there was an error when setting
+ * the socket option.
+ * @see SocketOption
+ */
public void setOption(SocketOption key, int val)
throws IOException
{
sd.setOption(key, val);
}
- public void setOption(SocketOption key, boolean val)
+ /**
+ * Sets the state of the {@code SocketOption} for this socket.
+ *
+ * @param key the {@code SocketOption} to set.
+ * @param on the state whether this option is enabled or not.
+ *
+ * @throws InvalidArgumentException
+ * if the socket does not support setting boolean values.
+ * @throws OperationNotImplededException
+ * if the socket does not support this option.
+ * @throws IOException if there was an error when setting
+ * the socket option.
+ * @see SocketOption
+ */
+ public void setOption(SocketOption key, boolean on)
throws IOException
{
- sd.setOption(key, val);
+ sd.setOption(key, on);
}
- public void setOption(TcpOption key, boolean val)
+ /**
+ * Sets the state of the {@code TcpOption} for this socket.
+ *
+ * @param key the {@code TcpOption} to set.
+ * @param on the state whether this option is enabled or not.
+ *
+ * @throws InvalidArgumentException
+ * if the socket does not support setting boolean values.
+ * @throws OperationNotImplededException
+ * if the socket does not support this option.
+ * @throws IOException if there was an error when setting
+ * the socket option.
+ * @see TcpOption
+ */
+ public void setOption(TcpOption key, boolean on)
throws IOException
{
- sd.setOption(key, val);
+ sd.setOption(key, on);
}
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java?rev=1147743&r1=1147742&r2=1147743&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketServerEndpoint.java
Mon Jul 18 04:51:11 2011
@@ -27,6 +27,7 @@ import org.apache.commons.runtime.io.Clo
import org.apache.commons.runtime.io.Descriptor;
import org.apache.commons.runtime.io.OperationInProgressException;
import org.apache.commons.runtime.io.OperationWouldBlockException;
+import org.apache.commons.runtime.OperationNotImplementedException;
import org.apache.commons.runtime.OverflowException;
import org.apache.commons.runtime.Status;
@@ -58,12 +59,12 @@ public class SocketServerEndpoint extend
* Creates a new local server endpoint from the
* given socket descriptor.
*/
- public SocketServerEndpoint(SocketDescriptor sd)
+ public SocketServerEndpoint(Descriptor sd)
{
super(EndpointType.SOCKET);
if (sd == null)
throw new NullPointerException();
- this.sd = sd;
+ this.sd = (SocketDescriptor)sd;
}
@Override
@@ -152,7 +153,7 @@ public class SocketServerEndpoint extend
}
private static native int bind0(long fd, byte[] sa, int backlog);
- private static native long accept0(long fd, byte[] sa, boolean
block)
+ private static native long accept0(long fd, byte[] aa, boolean
block)
throws SocketException;
@Override
@@ -161,11 +162,31 @@ public class SocketServerEndpoint extend
{
if (bound)
throw new IOException(Local.sm.get("endpoint.EBOUND"));
- if (sd.closed())
+ if (sd.closed()) {
sd.create(endpoint.getFamily(), SocketType.STREAM, blocking);
- sa = new AbstractSocketAddress(endpoint);
+ // Set default options
+ // NOTICE: Options are taken from the Apache Web Server.
+ // and should be set up for any server.
+ sd.setOption(SocketOption.KEEPALIVE, true);
+ sd.setOption(TcpOption.NODELAY, true);
+ if (endpoint.getFamily() == AddressFamily.INET6) {
+ try {
+ sd.setOption(SocketOption.IPV6_V6ONLY, true);
+ } catch (OperationNotImplementedException u) {
+ // IPV6_V6ONLY might not be supported
+ // on all platforms
+ }
+ }
+
+ // NOTICE: REUSEADDR is set inside native bind0 call
+ // depending on the operating system.
+ }
if (backlog == 0)
backlog = LISTEN_BACKLOG;
+ sa = new AbstractSocketAddress(endpoint);
+ // Bind and listen on the socket.
+ // sa will be updated in case it had ephemeral port or
+ // its address was INADDR_ANY.
int rc = bind0(sd.fd(), sa.sockaddr(), backlog);
if (rc != 0) {
try {
@@ -191,9 +212,11 @@ public class SocketServerEndpoint extend
{
if (sd.closed())
throw new ClosedDescriptorException();
- long fd = accept0(sd.fd(), sa.sockaddr(), blocking);
+ byte[] aa = Address.alloc();
+ long fd = accept0(sd.fd(), aa, blocking);
SocketDescriptor ad = new SocketDescriptor(fd);
- return new SocketEndpoint(ad, sa);
+ SocketAddress ra = new AbstractSocketAddress(aa);
+ return new SocketEndpoint(ad, ra, sa);
}
@Override
@@ -210,4 +233,33 @@ public class SocketServerEndpoint extend
return sd.closed();
}
+ /**
+ * Gets the local port of this server endpoint is listening on.
+ *
+ * @return the local port number this server is listening on
+ * or {@code -1} if the socket is unbound.
+ */
+ public final int getLocalPort()
+ {
+ if (bound)
+ return sa.getPort();
+ else
+ return -1;
+ }
+
+ /**
+ * Gets the local socket address of this server endpoint or {@code null}
+ * if the socket is unbound. This is useful on multihomed hosts.
+ *
+ * @return the local socket address this socket is bound to.
+ */
+ public final SocketAddress getLocalAddress()
+ {
+ if (bound)
+ return sa;
+ else
+ return null;
+ }
+
+
}
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=1147743&r1=1147742&r2=1147743&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 Mon Jul 18
04:51:11 2011
@@ -16,6 +16,7 @@
#include "acr/jnitypes.h"
#include "acr/error.h"
+#include "acr/debug.h"
#include "acr/memory.h"
#include "acr/netapi.h"
#include "acr/unsafe.h"
@@ -294,7 +295,7 @@ ACR_NET_EXPORT(jint, SocketServerEndpoin
*/
if (aa->port == 0 || memcmp(&aa->sa.sin.sin_addr, any, aa->iplen) == 0) {
/* Get the real address for the bound socket.
- */
+ */
if ((rc = AcrGetLocalAddr(fd, aa)) != 0)
goto finally;
}
@@ -306,7 +307,7 @@ finally:
}
ACR_NET_EXPORT(jlong, SocketServerEndpoint, accept0)(JNI_STDARGS, jlong fp,
- jbyteArray ba,
+ jbyteArray ra,
jboolean block)
{
int sd;
@@ -323,9 +324,10 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
flags |= SOCK_NONBLOCK;
# endif
#endif
- ad = AcrSdRetain(fd);
memset(&aa, 0, sizeof(aa));
- aalen = ISIZEOF(struct sockaddr_un);
+ aalen = SSIZEOF(acr_sockaddr_t);
+
+ ad = AcrSdRetain(fd);
do {
#if HAVE_ACCEPT4
sd = accept4(ad, (struct sockaddr *)&aa.sa, &aalen, flags);
@@ -412,5 +414,77 @@ ACR_NET_EXPORT(jlong, SocketServerEndpoi
if (sp->timeout == 0)
sp->timeout = -1;
}
+ switch (aa.sa.sin.sin_family) {
+ case AF_INET:
+ aa.addrlen = 16;
+ aa.iplen = ISIZEOF(struct in_addr);
+ break;
+ case AF_INET6:
+ aa.addrlen = 46;
+ aa.iplen = ISIZEOF(struct in6_addr);
+ default:
+#if defined(DEBUG) || defined(_DEBUG)
+ ACR_DEBUG_TRACE("Unexpected address family %d\n", aa.family);
+#endif
+ break;
+ }
+#if defined(DEBUG) || defined(_DEBUG)
+ if (aa.addrlen != (int)aalen) {
+ ACR_DEBUG_TRACE("Address length missmatch. Expected %d, found %d\n",
aa.addrlen, (int)aalen);
+ }
+#endif
+ aa.salen = aa.iplen;
+ aa.family = aa.sa.sin.sin_family;
+ aa.port = ntohs(aa.sa.sin.sin_port);
+ (*env)->SetByteArrayRegion(env, ra, 0, ISIZEOF(acr_sockaddr_t), (jbyte
*)&aa);
return P2J(sp);
}
+
+ACR_NET_EXPORT(jint, SocketEndpoint, connect0)(JNI_STDARGS, jlong fp,
+ jbyteArray cb, jint timeout)
+{
+ int rc;
+ int sd;
+ acr_sockaddr_t *ca = SOCKADDR_CAST(cb);
+ acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+ sd = AcrSdRetain(fd);
+ if (timeout == 0)
+ timeout = fd->timeout;
+ if (timeout > 0 && !ACR_HASFLAG(fd, ACR_SO_NONBLOCK)) {
+ /* Turn the socket to non-blocking mode
+ */
+ if ((rc = AcrNonblock(sd, 1)) != 0)
+ goto finally;
+ }
+ do {
+ /* Restartable connect */
+ rc = connect(sd, (const struct sockaddr *)&ca->sa.sin, ca->salen);
+ } while (rc == -1 && errno == EINTR);
+
+ if (rc == -1)
+ rc = errno;
+ SOCKADDR_RELEASE(cb, ca);
+ if (rc != 0) {
+ if (timeout > 0) {
+ if (rc == EINPROGRESS || rc == EALREADY) {
+ rc = AcrWaitIO(fd->s, timeout, POLLOUT);
+#if defined(SO_ERROR)
+ if (rc == 0) {
+ int err;
+ socklen_t len = sizeof(err);
+ if (getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&err,
&len) == -1);
+ rc = errno;
+ if (err != 0)
+ rc = err;
+ }
+#endif
+ }
+ if (!ACR_HASFLAG(fd, ACR_SO_NONBLOCK))
+ AcrNonblock(fd->s, 0);
+ }
+ }
+finally:
+ AcrSdRelease(fd);
+ return rc;
+}
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=1147743&r1=1147742&r2=1147743&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 Mon Jul
18 04:51:11 2011
@@ -119,7 +119,6 @@ ACR_NET_EXPORT(void, LocalServerEndpoint
}
ACR_NET_EXPORT(jlong, LocalServerEndpoint, accept0)(JNI_STDARGS, jlong fp,
- jbyteArray ba,
jboolean block)
{
int sd;
@@ -164,17 +163,6 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
}
}
#endif
-#if !TCP_NODELAY_INHERITED
- if (ACR_HASFLAG(fd, ACR_TCP_NODELAY)) {
- int on = 1;
- if (setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (void *)&on,
SSIZEOF(int)) != 0) {
- int rc = ACR_GET_NETOS_ERROR();
- r_close(sd);
- ACR_THROW_NET_ERROR(rc);
- return 0;
- }
- }
-#endif
if (block == JNI_FALSE) {
int rc = 0;
#if O_NONBLOCK_INHERITED
@@ -210,10 +198,6 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
return 0;
}
sp->type = ACR_DT_LOCALSOCK;
- /* Inherit nodelay flag
- * It's always valid cause we either inherit or explicitly set that flag.
- */
- sp->flags = fd->flags & ACR_TCP_NODELAY;
#if O_NONBLOCK_INHERITED
/* Inherit timeout */
sp->timeout = fd->timeout;
@@ -226,7 +210,6 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
sp->timeout = 0;
}
else {
- ACR_CLRFLAG(sp, ACR_SO_NONBLOCK);
if (sp->timeout == 0)
sp->timeout = -1;
}
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=1147743&r1=1147742&r2=1147743&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 Mon Jul
18 04:51:11 2011
@@ -194,12 +194,10 @@ ACR_NET_EXPORT(void, LocalServerEndpoint
}
ACR_NET_EXPORT(jlong, LocalServerEndpoint, accept0)(JNI_STDARGS, jlong fp,
- jbyteArray ba,
jboolean block)
{
SOCKET sd;
SOCKET ad;
- acr_sockaddr_t *aa;
struct sockaddr_in sa;
int sas = ISIZEOF(sa);
acr_sd_t *sp;
@@ -242,14 +240,6 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
closesocket(sd);
return 0;
}
- aa = SOCKADDR_CAST(ba);
- if (aa != 0) {
- /* The only thing that is unique is port
- */
- aa->port = ntohs(sa.sin_port);
- }
- SOCKADDR_RELEASE(ba, aa);
-
sp->type = ACR_DT_LOCALSOCK;
sp->flags = fd->flags & ACR_SO_NONBLOCK;
sp->timeout = fd->timeout;
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c?rev=1147743&r1=1147742&r2=1147743&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/netaddr.c Mon Jul 18
04:51:11 2011
@@ -447,18 +447,15 @@ sockaddr_vars_set(acr_sockaddr_t *addr,
if (family == AF_INET) {
addr->salen = ISIZEOF(struct sockaddr_in);
addr->addrlen = 16;
- addr->iplen = sizeof(struct in_addr);
}
else if (family == AF_INET6) {
addr->salen = ISIZEOF(struct sockaddr_in6);
addr->addrlen = 46;
- addr->iplen = sizeof(struct in6_addr);
}
#if HAVE_SYS_UN_H
else if (family == AF_LOCAL) {
addr->salen = ISIZEOF(struct sockaddr_un);
addr->addrlen = ISIZEOF(addr->sa.unx.sun_path);
- addr->iplen = addr->addrlen;
}
#endif
else {
@@ -466,6 +463,7 @@ sockaddr_vars_set(acr_sockaddr_t *addr,
addr->addrlen = 0;
addr->iplen = 0;
}
+ addr->iplen = addr->salen;
}
static int
Copied:
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestLocalEndpoint.java
(from r1147618,
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestPosixEndpoint.java)
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestLocalEndpoint.java?p2=commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestLocalEndpoint.java&p1=commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestPosixEndpoint.java&r1=1147618&r2=1147743&rev=1147743&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestPosixEndpoint.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestLocalEndpoint.java
Mon Jul 18 04:51:11 2011
@@ -24,7 +24,7 @@ import org.testng.Assert;
import org.apache.commons.runtime.io.Descriptor;
-public class TestPosixEndpoint extends Assert
+public class TestLocalEndpoint extends Assert
{
@BeforeSuite
Added:
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestServerEndpoint.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestServerEndpoint.java?rev=1147743&view=auto
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestServerEndpoint.java
(added)
+++
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestServerEndpoint.java
Mon Jul 18 04:51:11 2011
@@ -0,0 +1,157 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.runtime.net;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import org.testng.annotations.*;
+import org.testng.Assert;
+
+import org.apache.commons.runtime.io.Descriptor;
+
+public class TestServerEndpoint extends Assert
+{
+
+ private Object sync = new Object();
+
+ class Acceptor extends Thread
+ {
+ Selector ps;
+ SocketServerEndpoint ss;
+ public volatile boolean running = true;
+
+ public Acceptor(SocketServerEndpoint ss, Selector ps)
+ {
+ this.ss = ss;
+ this.ps = ps;
+ }
+
+ public void run()
+ {
+ SelectionKey sk;
+ try {
+ sk = ss.register(ps, SelectionKey.OP_ACCEPT);
+ assertEquals(ps.size(), 1);
+ } catch (Exception x) {
+ fail("Acceptor setup failed " + x.toString());
+ running = false;
+ return;
+ }
+ while (true) {
+ try {
+ synchronized (sync) {
+ // Notify that we are ready to
+ // accept the connections
+ sync.notifyAll();
+ }
+ System.out.print("Accepting connection ... ");
+ List<SelectionKey> set = ps.select();
+ if (set.size() == 0) {
+ System.out.println("interrupted.");
+ break;
+ }
+ System.out.println("done (" + set.size() + " connection)");
+ assertEquals(set.size(), 1);
+ sk = set.get(0);
+ SocketEndpoint e =
((SocketServerEndpoint)sk.endpoint()).accept();
+ assertNotNull(e.descriptor());
+ // Another select with zero timeout
+ set = ps.select(0);
+ assertEquals(set.size(), 0);
+ } catch (Exception x) {
+ fail("Accept failed " + x.toString());
+ break;
+ }
+ }
+ try {
+ ss.close();
+ } catch (Exception x) {
+ fail("Acceptor shutdown failed " + x.toString());
+ }
+ running = false;
+ System.out.println("Accepting thread finished");
+ synchronized (sync) {
+ // Notify that we are ready to
+ // accept the connections
+ sync.notifyAll();
+ }
+ }
+ }
+
+ @Test(groups = { "core" })
+ public void connectServerEndpoint()
+ throws Exception
+ {
+ System.out.println("Testing ServerSocketEndpoint ...");
+
+ Selector ps = Selector.open(EndpointType.LOCAL);
+ SocketServerEndpoint ss = new SocketServerEndpoint();
+ InetSocketAddress sa = new InetSocketAddress("127.0.0.1", 0);
+ ss.configureBlocking(false);
+ assertEquals(ss.getLocalPort(), -1);
+ ss.bind(sa);
+ assertFalse(ss.getLocalPort() == 0);
+ // keyFor() should return null since the endpoint
+ // is not yet registered.
+ assertNull(ss.keyFor(ps));
+ // ps.setAutoCancel(true);
+ Acceptor aw = new Acceptor(ss, ps);
+ aw.setName("TestSocketAcceptorThread");
+ aw.start();
+ try {
+ synchronized (sync) {
+ // Wait until Acceptor is ready to accept connections
+ //
+ sync.wait();
+ }
+ Thread.sleep(100);
+ } catch (InterruptedException x) {
+ // Ignore
+ }
+ // By this time the key is set up.
+ assertNotNull(ss.keyFor(ps));
+ // Connect to the Acceptor
+ //
+ SocketEndpoint cs = new SocketEndpoint();
+ cs.connect(ss.getLocalAddress());
+ assertTrue(cs.isBlocking());
+ cs.close();
+ ps.interrupt();
+ try {
+ synchronized (sync) {
+ // Wait until Acceptor process the accepted connection
+ //
+ if (aw.running)
+ sync.wait();
+ }
+ Thread.sleep(200);
+ } catch (InterruptedException x) {
+ // Ignore
+ }
+ System.out.print("Interrupting selector ... ");
+ ps.interrupt();
+ System.out.println("OK");
+ // Wait for the Acceptor thread to finish
+ aw.join();
+ List<SelectionKey> set = ps.clear();
+ // Shoud equal zero if autoCancel is set to true
+ assertEquals(set.size(), 1);
+ ps.close();
+ }
+
+}
Propchange:
commons/sandbox/runtime/trunk/src/main/test/org/apache/commons/runtime/TestServerEndpoint.java
------------------------------------------------------------------------------
svn:eol-style = native