mirror of
https://github.com/corda/corda.git
synced 2025-02-07 19:40:25 +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)
|
doFinishConnect(JNIEnv* e, int socket)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
@ -289,12 +289,9 @@ doFinishConnect(JNIEnv* e, int socket)
|
|||||||
|
|
||||||
if (r != 0 or size != sizeof(int)) {
|
if (r != 0 or size != sizeof(int)) {
|
||||||
throwIOException(e);
|
throwIOException(e);
|
||||||
} else if (einProgress(error)) {
|
} else if (error and not einProgress(error)) {
|
||||||
return false;
|
|
||||||
} else if (error != 0) {
|
|
||||||
throwIOException(e, socketErrorString(e, error));
|
throwIOException(e, socketErrorString(e, error));
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -426,12 +423,12 @@ Java_java_nio_channels_SocketChannel_natDoConnect(JNIEnv *e,
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jboolean JNICALL
|
extern "C" JNIEXPORT void JNICALL
|
||||||
Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e,
|
Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e,
|
||||||
jclass,
|
jclass,
|
||||||
jint socket)
|
jint socket)
|
||||||
{
|
{
|
||||||
return doFinishConnect(e, socket);
|
doFinishConnect(e, socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
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 int socketFD();
|
||||||
|
|
||||||
|
abstract void handleReadyOps(int ops);
|
||||||
|
|
||||||
public abstract SelectableChannel configureBlocking(boolean v)
|
public abstract SelectableChannel configureBlocking(boolean v)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
|
||||||
|
@ -18,12 +18,13 @@ import java.net.Socket;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
public class SocketChannel extends SelectableChannel
|
public class SocketChannel extends SelectableChannel
|
||||||
implements ReadableByteChannel, WritableByteChannel
|
implements ReadableByteChannel, GatheringByteChannel
|
||||||
{
|
{
|
||||||
public static final int InvalidSocket = -1;
|
public static final int InvalidSocket = -1;
|
||||||
|
|
||||||
int socket = InvalidSocket;
|
int socket = InvalidSocket;
|
||||||
boolean connected = false;
|
boolean connected = false;
|
||||||
|
boolean readyToConnect = false;
|
||||||
boolean blocking = true;
|
boolean blocking = true;
|
||||||
|
|
||||||
public static SocketChannel open() throws IOException {
|
public static SocketChannel open() throws IOException {
|
||||||
@ -66,8 +67,18 @@ public class SocketChannel extends SelectableChannel
|
|||||||
|
|
||||||
public boolean finishConnect() throws IOException {
|
public boolean finishConnect() throws IOException {
|
||||||
if (! connected) {
|
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;
|
return connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,6 +128,23 @@ public class SocketChannel extends SelectableChannel
|
|||||||
return w;
|
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() {
|
private void closeSocket() {
|
||||||
natCloseSocket(socket);
|
natCloseSocket(socket);
|
||||||
}
|
}
|
||||||
@ -125,6 +153,12 @@ public class SocketChannel extends SelectableChannel
|
|||||||
return socket;
|
return socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void handleReadyOps(int ops) {
|
||||||
|
if ((ops & SelectionKey.OP_CONNECT) != 0) {
|
||||||
|
readyToConnect = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class Handle extends Socket {
|
public class Handle extends Socket {
|
||||||
public void setTcpNoDelay(boolean on) throws SocketException {
|
public void setTcpNoDelay(boolean on) throws SocketException {
|
||||||
natSetTcpNoDelay(socket, on);
|
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)
|
private static native int natDoConnect(String host, int port, boolean blocking, boolean[] connected)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
private static native boolean natFinishConnect(int socket)
|
private static native void natFinishConnect(int socket)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking)
|
private static native int natRead(int socket, byte[] buffer, int offset, int length, boolean blocking)
|
||||||
throws IOException;
|
throws IOException;
|
||||||
|
@ -96,6 +96,7 @@ class SocketSelector extends Selector {
|
|||||||
int ready = natUpdateReadySet(socket, key.interestOps(), state);
|
int ready = natUpdateReadySet(socket, key.interestOps(), state);
|
||||||
key.readyOps(ready);
|
key.readyOps(ready);
|
||||||
if (ready != 0) {
|
if (ready != 0) {
|
||||||
|
c.handleReadyOps(ready);
|
||||||
selectedKeys.add(key);
|
selectedKeys.add(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user