fix false positive return from SocketChannel.finishConnect

This fixes a bug in finishConnect such that it would return true even
if the socket had not yet connected successfully.
This commit is contained in:
Joel Dice 2011-01-11 18:29:48 -07:00
parent 4f0dccb53c
commit eb3a9f010b
5 changed files with 64 additions and 10 deletions

View File

@ -279,7 +279,7 @@ doListen(JNIEnv* e, int s, sockaddr_in* address)
}
}
bool
void
doFinishConnect(JNIEnv* e, int socket)
{
int error;
@ -289,12 +289,9 @@ doFinishConnect(JNIEnv* e, int socket)
if (r != 0 or size != sizeof(int)) {
throwIOException(e);
} else if (einProgress(error)) {
return false;
} else if (error != 0) {
} else if (error and not einProgress(error)) {
throwIOException(e, socketErrorString(e, error));
}
return true;
}
bool
@ -426,12 +423,12 @@ Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e,
return s;
}
extern "C" JNIEXPORT jboolean JNICALL
extern "C" JNIEXPORT void JNICALL
Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e,
jclass,
jint socket)
{
return doFinishConnect(e, socket);
doFinishConnect(e, socket);
}
extern "C" JNIEXPORT jint JNICALL

View File

@ -0,0 +1,20 @@
/* Copyright (c) 2011, 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.nio.channels;
import java.io.IOException;
import java.nio.ByteBuffer;
public interface GatheringByteChannel extends WritableByteChannel {
public long write(ByteBuffer[] srcs) throws IOException;
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException;
}

View File

@ -19,6 +19,8 @@ public abstract class SelectableChannel implements Channel {
abstract int socketFD();
abstract void handleReadyOps(int ops);
public abstract SelectableChannel configureBlocking(boolean v)
throws IOException;

View File

@ -18,12 +18,13 @@ import java.net.Socket;
import java.nio.ByteBuffer;
public class SocketChannel extends SelectableChannel
implements ReadableByteChannel, WritableByteChannel
implements ReadableByteChannel, GatheringByteChannel
{
public static final int InvalidSocket = -1;
int socket = InvalidSocket;
boolean connected = false;
boolean readyToConnect = false;
boolean blocking = true;
public static SocketChannel open() throws IOException {
@ -66,8 +67,18 @@ public class SocketChannel extends SelectableChannel
public boolean finishConnect() throws IOException {
if (! connected) {
connected = natFinishConnect(socket);
while (blocking && ! readyToConnect) {
Selector selector = Selector.open();
SelectionKey key = register(selector, SelectionKey.OP_CONNECT, null);
selector.select();
}
natFinishConnect(socket);
connected = readyToConnect;
}
return connected;
}
@ -117,6 +128,23 @@ public class SocketChannel extends SelectableChannel
return w;
}
public long write(ByteBuffer[] srcs) throws IOException {
return write(srcs, 0, srcs.length);
}
public long write(ByteBuffer[] srcs, int offset, int length)
throws IOException
{
long total = 0;
for (int i = offset; i < offset + length; ++i) {
total += write(srcs[i]);
if (srcs[i].hasRemaining()) {
return total;
}
}
return total;
}
private void closeSocket() {
natCloseSocket(socket);
}
@ -125,6 +153,12 @@ public class SocketChannel extends SelectableChannel
return socket;
}
void handleReadyOps(int ops) {
if ((ops & SelectionKey.OP_CONNECT) != 0) {
readyToConnect = true;
}
}
public class Handle extends Socket {
public void setTcpNoDelay(boolean on) throws SocketException {
natSetTcpNoDelay(socket, on);
@ -139,7 +173,7 @@ 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)
private static native void natFinishConnect(int socket)
throws IOException;
private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking)
throws IOException;

View File

@ -96,6 +96,7 @@ class SocketSelector extends Selector {
int ready = natUpdateReadySet(socket, key.interestOps(), state);
key.readyOps(ready);
if (ready != 0) {
c.handleReadyOps(ready);
selectedKeys.add(key);
}
}