diff --git a/classpath/java-nio.cpp b/classpath/java-nio.cpp index 86eb9aa6c5..e5a0e345ff 100644 --- a/classpath/java-nio.cpp +++ b/classpath/java-nio.cpp @@ -26,6 +26,7 @@ # include # include # include +# include #endif #define java_nio_channels_SelectionKey_OP_READ 1L @@ -88,6 +89,26 @@ throwIOException(JNIEnv* e) throwIOException(e, errorString(e)); } +void +throwSocketException(JNIEnv* e, const char* s) +{ + throwNew(e, "java/net/SocketException", s); +} + +void +throwSocketException(JNIEnv* e, jbyteArray a) +{ + jbyte* s = static_cast(e->GetPrimitiveArrayCritical(a, 0)); + throwSocketException(e, reinterpret_cast(s)); + e->ReleasePrimitiveArrayCritical(a, s, 0); +} + +void +throwSocketException(JNIEnv* e) +{ + throwSocketException(e, errorString(e)); +} + void init(JNIEnv* e, sockaddr_in* address, jstring hostString, jint port) { @@ -152,6 +173,19 @@ makeNonblocking(JNIEnv* e, int d) return true; } +bool +setTcpNoDelay(JNIEnv* e, int d, bool on) +{ + int flag = on; + int r = setsockopt + (d, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&flag), sizeof(int)); + if (r < 0) { + throwSocketException(e); + return false; + } + return true; +} + void doListen(JNIEnv* e, int s, sockaddr_in* address) { @@ -277,6 +311,15 @@ Java_java_nio_channels_ServerSocketChannel_natDoListen(JNIEnv *e, return s; } +extern "C" JNIEXPORT void JNICALL +Java_java_nio_channels_SocketChannel_natSetTcpNoDelay(JNIEnv *e, + jclass, + jint socket, + jboolean on) +{ + setTcpNoDelay(e, socket, on); +} + extern "C" JNIEXPORT jint JNICALL Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e, jclass, diff --git a/classpath/java/net/Socket.java b/classpath/java/net/Socket.java new file mode 100644 index 0000000000..602b24a19e --- /dev/null +++ b/classpath/java/net/Socket.java @@ -0,0 +1,15 @@ +/* Copyright (c) 2008, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.net; + +public abstract class Socket { + public abstract void setTcpNoDelay(boolean on) throws SocketException; +} diff --git a/classpath/java/net/SocketException.java b/classpath/java/net/SocketException.java new file mode 100644 index 0000000000..f0a9ee2ac3 --- /dev/null +++ b/classpath/java/net/SocketException.java @@ -0,0 +1,23 @@ +/* Copyright (c) 2008, Avian Contributors + + Permission to use, copy, modify, and/or distribute this software + for any purpose with or without fee is hereby granted, provided + that the above copyright notice and this permission notice appear + in all copies. + + There is NO WARRANTY for this software. See license.txt for + details. */ + +package java.net; + +import java.io.IOException; + +public class SocketException extends IOException { + public SocketException(String message) { + super(message); + } + + public SocketException() { + this(null); + } +} diff --git a/classpath/java/nio/channels/ServerSocketChannel.java b/classpath/java/nio/channels/ServerSocketChannel.java index c1311b5116..f84c9626bc 100644 --- a/classpath/java/nio/channels/ServerSocketChannel.java +++ b/classpath/java/nio/channels/ServerSocketChannel.java @@ -16,11 +16,21 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.net.ServerSocket; -public class ServerSocketChannel extends SocketChannel { +public class ServerSocketChannel extends SelectableChannel { + private final SocketChannel channel = new SocketChannel(); + public static ServerSocketChannel open() { return new ServerSocketChannel(); } + public SelectableChannel configureBlocking(boolean v) { + return channel.configureBlocking(v); + } + + public void close() throws IOException { + channel.close(); + } + public SocketChannel accept() throws Exception { SocketChannel c = new SocketChannel(); c.socket = doAccept(); @@ -33,7 +43,7 @@ public class ServerSocketChannel extends SocketChannel { } private int doAccept() throws IOException { - return natDoAccept(socket); + return natDoAccept(channel.socket); } private int doListen(String host, int port) throws IOException { @@ -50,7 +60,7 @@ public class ServerSocketChannel extends SocketChannel { } catch (ClassCastException e) { throw new IllegalArgumentException(); } - socket = doListen(a.getHostName(), a.getPort()); + channel.socket = doListen(a.getHostName(), a.getPort()); } } diff --git a/classpath/java/nio/channels/SocketChannel.java b/classpath/java/nio/channels/SocketChannel.java index cc4b2abb90..aa723030db 100644 --- a/classpath/java/nio/channels/SocketChannel.java +++ b/classpath/java/nio/channels/SocketChannel.java @@ -11,8 +11,10 @@ package java.nio.channels; import java.io.IOException; +import java.net.SocketException; import java.net.SocketAddress; import java.net.InetSocketAddress; +import java.net.Socket; import java.nio.ByteBuffer; public class SocketChannel extends SelectableChannel @@ -20,8 +22,8 @@ public class SocketChannel extends SelectableChannel { public static final int InvalidSocket = -1; - protected int socket = InvalidSocket; - protected boolean connected = false; + int socket = InvalidSocket; + boolean connected = false; public static SocketChannel open() { return new SocketChannel(); @@ -32,6 +34,10 @@ public class SocketChannel extends SelectableChannel return this; } + public Socket socket() { + return new Handle(); + } + public boolean connect(SocketAddress address) throws Exception { InetSocketAddress a; try { @@ -87,6 +93,15 @@ public class SocketChannel extends SelectableChannel return socket; } + public class Handle extends Socket { + public void setTcpNoDelay(boolean on) throws SocketException { + natSetTcpNoDelay(socket, on); + } + } + + private static native void natSetTcpNoDelay(int socket, boolean on) + throws SocketException; + private static native int natDoConnect(String host, int port, boolean[] connected) throws Exception; private static native int natRead(int socket, byte[] buffer, int offset, int length)