Skip to content

Commit

Permalink
common,native: Properly handle virtual non-blocking connect, read
Browse files Browse the repository at this point in the history
On Windows, "connect" may return "already is connected", whereas a
non-blocking read may erroneously be thrown as an exception.
  • Loading branch information
kohlschuetter committed Apr 18, 2024
1 parent 4923337 commit 6e7e2ca
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ final boolean connect0(SocketAddress addr, int connectTimeout) throws IOExceptio
core.configureVirtualBlocking(true);
}
try {
success = NativeUnixSocket.connect(ab, ab.limit(), fd, -1);
success = NativeUnixSocket.connect(ab, ab.limit(), fd, -2);
if (!success && virtualBlocking) {
// try again (non-blocking timeout)
if (virtualConnectTimeout == null) {
Expand Down Expand Up @@ -627,6 +627,8 @@ public int read(byte[] buf, int off, int len) throws IOException {
opt = defaultOpt;
}

int read;

boolean park = false;
virtualThreadLoop : do {
if (virtualBlocking) {
Expand All @@ -638,8 +640,17 @@ public int read(byte[] buf, int off, int len) throws IOException {
}

try {
return NativeUnixSocket.read(fdesc, buf, off, len, opt, ancillaryDataSupport,
read = NativeUnixSocket.read(fdesc, buf, off, len, opt, ancillaryDataSupport,
socketTimeout.get());
if (read == -2) {
if (virtualBlocking) {
// sleep again
park = true;
continue virtualThreadLoop;
} else {
read = 0;
}
}
} catch (SocketTimeoutException e) {
if (virtualBlocking) {
// sleep again
Expand All @@ -656,7 +667,10 @@ public int read(byte[] buf, int off, int len) throws IOException {
core.configureVirtualBlocking(false);
}
}
break; // NOPMD.AvoidBranchingStatementAsLastInLoop virtualThreadLoop
} while (true); // NOPMD.WhileLoopWithLiteralBoolean

return read;
}

@SuppressWarnings("PMD.CognitiveComplexity")
Expand Down Expand Up @@ -695,6 +709,15 @@ public int read() throws IOException {
int byteRead = NativeUnixSocket.read(fdesc, null, 0, 1, opt, ancillaryDataSupport,
socketTimeout.get());
if (byteRead < 0) {
if (byteRead == -2) {
if (virtualBlocking) {
// sleep again
park = true;
continue virtualThreadLoop;
} else {
byteRead = -1;
}
}
eofReached.set(true);
return -1;
} else {
Expand Down
12 changes: 11 additions & 1 deletion junixsocket-native/src/main/c/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ JNIEXPORT jboolean JNICALL Java_org_newsclub_net_unix_NativeUnixSocket_connect
JNIEnv * env, jclass clazz CK_UNUSED, jobject ab, jint abLen, jobject fd,
jlong expectedInode)
{
jboolean existingConnectOK;
if(expectedInode == -2) {
expectedInode = -1;
existingConnectOK = true;
} else {
existingConnectOK = false;
}

jux_sockaddr_t *addr = (*env)->GetDirectBufferAddress(env, ab);
socklen_t addrLength = (socklen_t)abLen;
if(addrLength == 0) {
Expand Down Expand Up @@ -80,7 +88,9 @@ JNIEXPORT jboolean JNICALL Java_org_newsclub_net_unix_NativeUnixSocket_connect
} while(ret == -1 && myErr == EINTR);

if(ret == -1) {
if(checkNonBlocking(socketHandle, myErr)) {
if(myErr == EISCONN && existingConnectOK) {
return true;
} else if(checkNonBlocking(socketHandle, myErr)) {
// non-blocking connect
return false;
} else {
Expand Down
8 changes: 6 additions & 2 deletions junixsocket-native/src/main/c/receive.c
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,12 @@ JNIEXPORT jint JNICALL Java_org_newsclub_net_unix_NativeUnixSocket_read(
jint returnValue;
if(count < 0) {
// read(2) returns -1 on error. Java throws an Exception.
_throwErrnumException(env, errno, fd);
returnValue = -1;
if(errno == EWOULDBLOCK) {
returnValue = -2;
} else {
_throwErrnumException(env, errno, fd);
returnValue = -1;
}
} else if(count == 0) {
// read(2)/recv return 0 on EOF. Java returns -1.
returnValue = -1;
Expand Down

0 comments on commit 6e7e2ca

Please sign in to comment.