mirror of
https://github.com/corda/corda.git
synced 2025-01-31 16:35:43 +00:00
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:
parent
4f0dccb53c
commit
eb3a9f010b
@ -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
|
||||
|
20
classpath/java/nio/channels/GatheringByteChannel.java
Normal file
20
classpath/java/nio/channels/GatheringByteChannel.java
Normal 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;
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user