From 59ba4aecf29ebd4ff449a9ccebfca18d5f6d445b Mon Sep 17 00:00:00 2001 From: Joel Dice Date: Thu, 8 Oct 2009 16:26:20 -0600 Subject: [PATCH] implement non-blocking socket connections --- classpath/java-nio.cpp | 31 ++++++++++++++++--- classpath/java/nio/channels/SelectionKey.java | 6 +++- .../java/nio/channels/SocketChannel.java | 6 ++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/classpath/java-nio.cpp b/classpath/java-nio.cpp index 11765dcfad..7d0d828423 100644 --- a/classpath/java-nio.cpp +++ b/classpath/java-nio.cpp @@ -36,6 +36,7 @@ #define java_nio_channels_SelectionKey_OP_READ 1L #define java_nio_channels_SelectionKey_OP_WRITE 4L +#define java_nio_channels_SelectionKey_OP_CONNECT 8L #define java_nio_channels_SelectionKey_OP_ACCEPT 16L #ifdef PLATFORM_WINDOWS @@ -371,6 +372,21 @@ Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e, return s; } +extern "C" JNIEXPORT jboolean JNICALL +Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e, + jclass, + jint socket) +{ + int error; + socklen_t size = sizeof(int); + int r = getsockopt(socket, SOL_SOCKET, SO_ERROR, + reinterpret_cast(&error), &size); + if (r != 0 or size != sizeof(int) or error != 0) { + throwIOException(e); + } + return true; +} + extern "C" JNIEXPORT jint JNICALL Java_java_nio_channels_SocketChannel_natRead(JNIEnv *e, jclass, @@ -626,7 +642,8 @@ Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(JNIEnv *, FD_CLR(static_cast(socket), &(s->read)); } - if (interest & java_nio_channels_SelectionKey_OP_WRITE) { + if (interest & (java_nio_channels_SelectionKey_OP_WRITE | + java_nio_channels_SelectionKey_OP_CONNECT)) { FD_SET(static_cast(socket), &(s->write)); if (max < socket) max = socket; } else { @@ -748,10 +765,16 @@ Java_java_nio_channels_SocketSelector_natUpdateReadySet(JNIEnv *, jclass, } } - if ((interest & java_nio_channels_SelectionKey_OP_WRITE) - and FD_ISSET(socket, &(s->write))) { - ready |= java_nio_channels_SelectionKey_OP_WRITE; + if (FD_ISSET(socket, &(s->write))) { + if (interest & java_nio_channels_SelectionKey_OP_WRITE) { + ready |= java_nio_channels_SelectionKey_OP_WRITE; + } + + if (interest & java_nio_channels_SelectionKey_OP_CONNECT) { + ready |= java_nio_channels_SelectionKey_OP_CONNECT; + } } + return ready; } diff --git a/classpath/java/nio/channels/SelectionKey.java b/classpath/java/nio/channels/SelectionKey.java index fbb1159d92..00e251d7e3 100644 --- a/classpath/java/nio/channels/SelectionKey.java +++ b/classpath/java/nio/channels/SelectionKey.java @@ -13,8 +13,8 @@ package java.nio.channels; public class SelectionKey { public static final int OP_READ = 1 << 0; public static final int OP_WRITE = 1 << 2; + public static final int OP_CONNECT = 1 << 3; public static final int OP_ACCEPT = 1 << 4; -// public static final int OP_CONNECT = 1 << 3; private final SelectableChannel channel; private final Selector selector; @@ -57,6 +57,10 @@ public class SelectionKey { return (readyOps & OP_WRITE) != 0; } + public boolean isConnectable() { + return (readyOps & OP_CONNECT) != 0; + } + public boolean isAcceptable() { return (readyOps & OP_ACCEPT) != 0; } diff --git a/classpath/java/nio/channels/SocketChannel.java b/classpath/java/nio/channels/SocketChannel.java index c6879d3a8a..a452085248 100644 --- a/classpath/java/nio/channels/SocketChannel.java +++ b/classpath/java/nio/channels/SocketChannel.java @@ -58,6 +58,10 @@ public class SocketChannel extends SelectableChannel return connected; } + public boolean finishConnect() throws IOException { + return natFinishConnect(socket); + } + public void close() throws IOException { if (isOpen()) { super.close(); @@ -126,6 +130,8 @@ public class SocketChannel extends SelectableChannel private static native int natDoConnect(String host, int port, boolean blocking, boolean[] connected) throws IOException; + private static native boolean natFinishConnect(int socket) + throws IOException; private static native int natRead(int socket, byte[] buffer, int offset, int length) throws IOException; private static native int natWrite(int socket, byte[] buffer, int offset, int length)