|
38 | 38 | import java.nio.channels.SelectionKey; |
39 | 39 | import java.util.Objects; |
40 | 40 | import java.util.Set; |
| 41 | +import java.util.concurrent.TimeUnit; |
41 | 42 | import java.util.concurrent.atomic.AtomicBoolean; |
42 | 43 | import java.util.concurrent.atomic.AtomicInteger; |
43 | 44 |
|
@@ -449,12 +450,40 @@ protected final void connect(InetAddress address, int port) throws IOException { |
449 | 450 | } |
450 | 451 |
|
451 | 452 | @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; |
454 | 483 | } |
455 | 484 |
|
456 | 485 | @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 { |
458 | 487 | if (addr == AFSocketAddress.INTERNAL_DUMMY_CONNECT) { |
459 | 488 | this.connected.set(true); |
460 | 489 | return true; |
|
0 commit comments