mirror of
https://github.com/corda/corda.git
synced 2025-01-23 12:58:35 +00:00
register socket with exceptfds when calling select on Windows
This allows us to get connection errors like WSAECONNREFUSED in non-blocking mode.
This commit is contained in:
parent
48cc14f8ed
commit
fdf9c5087b
@ -77,6 +77,19 @@ errorString(JNIEnv* e, int n)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline jbyteArray
|
||||||
|
socketErrorString(JNIEnv* e, int n)
|
||||||
|
{
|
||||||
|
#ifdef PLATFORM_WINDOWS
|
||||||
|
const unsigned size = 64;
|
||||||
|
char buffer[size];
|
||||||
|
snprintf(buffer, size, "wsa code: %d", n);
|
||||||
|
return charsToArray(e, buffer);
|
||||||
|
#else
|
||||||
|
return errorString(e, n);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
inline jbyteArray
|
inline jbyteArray
|
||||||
errorString(JNIEnv* e)
|
errorString(JNIEnv* e)
|
||||||
{
|
{
|
||||||
@ -243,6 +256,24 @@ doListen(JNIEnv* e, int s, sockaddr_in* address)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
doFinishConnect(JNIEnv* e, int socket)
|
||||||
|
{
|
||||||
|
int error;
|
||||||
|
socklen_t size = sizeof(int);
|
||||||
|
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR,
|
||||||
|
reinterpret_cast<char*>(&error), &size);
|
||||||
|
|
||||||
|
if (r != 0 or size != sizeof(int)) {
|
||||||
|
throwIOException(e);
|
||||||
|
} else if (einProgress(error)) {
|
||||||
|
return false;
|
||||||
|
} else if (error != 0) {
|
||||||
|
throwIOException(e, socketErrorString(e, error));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
doConnect(JNIEnv* e, int s, sockaddr_in* address)
|
doConnect(JNIEnv* e, int s, sockaddr_in* address)
|
||||||
{
|
{
|
||||||
@ -388,18 +419,7 @@ Java_java_nio_channels_SocketChannel_natFinishConnect(JNIEnv *e,
|
|||||||
jclass,
|
jclass,
|
||||||
jint socket)
|
jint socket)
|
||||||
{
|
{
|
||||||
int error;
|
return doFinishConnect(e, socket);
|
||||||
socklen_t size = sizeof(int);
|
|
||||||
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR,
|
|
||||||
reinterpret_cast<char*>(&error), &size);
|
|
||||||
if (r != 0 or size != sizeof(int)) {
|
|
||||||
throwIOException(e);
|
|
||||||
} else if (einProgress(error)) {
|
|
||||||
return false;
|
|
||||||
} else if (error != 0) {
|
|
||||||
throwIOException(e, errorString(e, error));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" JNIEXPORT jint JNICALL
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
@ -460,8 +480,10 @@ Java_java_nio_channels_SocketChannel_natThrowWriteError(JNIEnv *e,
|
|||||||
socklen_t size = sizeof(int);
|
socklen_t size = sizeof(int);
|
||||||
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR,
|
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR,
|
||||||
reinterpret_cast<char*>(&error), &size);
|
reinterpret_cast<char*>(&error), &size);
|
||||||
if (r != 0 or size != sizeof(int) or error != 0) {
|
if (r != 0 or size != sizeof(int)) {
|
||||||
throwIOException(e, errorString(e, error));
|
throwIOException(e);
|
||||||
|
} else if (error != 0) {
|
||||||
|
throwIOException(e, socketErrorString(e, error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -660,6 +682,7 @@ Java_java_nio_channels_SocketSelector_natSelectUpdateInterestSet(JNIEnv *,
|
|||||||
if (interest & (java_nio_channels_SelectionKey_OP_WRITE |
|
if (interest & (java_nio_channels_SelectionKey_OP_WRITE |
|
||||||
java_nio_channels_SelectionKey_OP_CONNECT)) {
|
java_nio_channels_SelectionKey_OP_CONNECT)) {
|
||||||
FD_SET(static_cast<unsigned>(socket), &(s->write));
|
FD_SET(static_cast<unsigned>(socket), &(s->write));
|
||||||
|
FD_SET(static_cast<unsigned>(socket), &(s->except));
|
||||||
if (max < socket) max = socket;
|
if (max < socket) max = socket;
|
||||||
} else {
|
} else {
|
||||||
FD_CLR(static_cast<unsigned>(socket), &(s->write));
|
FD_CLR(static_cast<unsigned>(socket), &(s->write));
|
||||||
@ -727,8 +750,10 @@ Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass,
|
|||||||
socklen_t size = sizeof(int);
|
socklen_t size = sizeof(int);
|
||||||
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR,
|
int r = getsockopt(socket, SOL_SOCKET, SO_ERROR,
|
||||||
reinterpret_cast<char*>(&error), &size);
|
reinterpret_cast<char*>(&error), &size);
|
||||||
if (r != 0 or size != sizeof(int) or error != 0) {
|
if (r != 0 or size != sizeof(int)) {
|
||||||
throwIOException(e);
|
throwIOException(e);
|
||||||
|
} else if (error != 0) {
|
||||||
|
throwIOException(e, socketErrorString(e, error));
|
||||||
}
|
}
|
||||||
s->control.setConnected(true);
|
s->control.setConnected(true);
|
||||||
}
|
}
|
||||||
@ -780,7 +805,7 @@ Java_java_nio_channels_SocketSelector_natUpdateReadySet(JNIEnv *, jclass,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(socket, &(s->write))) {
|
if (FD_ISSET(socket, &(s->write)) or FD_ISSET(socket, &(s->except))) {
|
||||||
if (interest & java_nio_channels_SelectionKey_OP_WRITE) {
|
if (interest & java_nio_channels_SelectionKey_OP_WRITE) {
|
||||||
ready |= java_nio_channels_SelectionKey_OP_WRITE;
|
ready |= java_nio_channels_SelectionKey_OP_WRITE;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user