Skip to content

Commit a320293

Browse files
committed
common: AFSocketImpl: Fix spurious connect timeouts
... as observed on Windows
1 parent 155d63a commit a320293

1 file changed

Lines changed: 32 additions & 3 deletions

File tree

junixsocket-common/src/main/java/org/newsclub/net/unix/AFSocketImpl.java

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.nio.channels.SelectionKey;
3939
import java.util.Objects;
4040
import java.util.Set;
41+
import java.util.concurrent.TimeUnit;
4142
import java.util.concurrent.atomic.AtomicBoolean;
4243
import java.util.concurrent.atomic.AtomicInteger;
4344

@@ -449,12 +450,40 @@ protected final void connect(InetAddress address, int port) throws IOException {
449450
}
450451

451452
@Override
452-
protected final void connect(SocketAddress addr, int connectTimeout) throws IOException {
453-
connect0(addr, connectTimeout);
453+
protected final void connect(SocketAddress addr, int connectTimeoutMs) throws IOException {
454+
connect0(addr, connectTimeoutMs);
455+
}
456+
457+
final boolean connect0(SocketAddress addr, int connectTimeoutMs) throws IOException {
458+
if (connectTimeoutMs <= 0) {
459+
return connect1(addr, 0);
460+
}
461+
462+
// Catch spurious timeouts (seen on Windows)
463+
int remainingTimeout = connectTimeoutMs;
464+
SocketTimeoutException ste = null;
465+
while (remainingTimeout > 0) {
466+
long time = System.nanoTime();
467+
try {
468+
return connect1(addr, remainingTimeout);
469+
} catch (SocketTimeoutException e) {
470+
if (ste == null) {
471+
ste = e;
472+
} else {
473+
ste.addSuppressed(ste);
474+
}
475+
}
476+
time = System.nanoTime() - time;
477+
remainingTimeout -= TimeUnit.NANOSECONDS.toMillis(time);
478+
}
479+
if (ste == null) {
480+
ste = new SocketTimeoutException();
481+
}
482+
throw ste;
454483
}
455484

456485
@SuppressWarnings({"PMD.CognitiveComplexity", "PMD.NcssCount"})
457-
final boolean connect0(SocketAddress addr, int connectTimeout) throws IOException {
486+
final boolean connect1(SocketAddress addr, int connectTimeout) throws IOException {
458487
if (addr == AFSocketAddress.INTERNAL_DUMMY_CONNECT) {
459488
this.connected.set(true);
460489
return true;

0 commit comments

Comments
 (0)