diff --git a/transport/src/main/java/io/netty/channel/nio/NioEventLoop.java b/transport/src/main/java/io/netty/channel/nio/NioEventLoop.java index c59e0109e03..677d1c81fe5 100644 --- a/transport/src/main/java/io/netty/channel/nio/NioEventLoop.java +++ b/transport/src/main/java/io/netty/channel/nio/NioEventLoop.java @@ -613,6 +613,18 @@ private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) { try { int readyOps = k.readyOps(); + // We first need to call finishConnect() before try to trigger a read(...) or write(...) as otherwise + // the NIO JDK channel implementation may throw a NotYetConnectedException. + if ((readyOps & SelectionKey.OP_CONNECT) != 0) { + // remove OP_CONNECT as otherwise Selector.select(..) will always return without blocking + // See https://github.com/netty/netty/issues/924 + int ops = k.interestOps(); + ops &= ~SelectionKey.OP_CONNECT; + k.interestOps(ops); + + unsafe.finishConnect(); + } + // Also check for readOps of 0 to workaround possible JDK bug which may otherwise lead // to a spin loop if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) { @@ -626,15 +638,6 @@ private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) { // Call forceFlush which will also take care of clear the OP_WRITE once there is nothing left to write ch.unsafe().forceFlush(); } - if ((readyOps & SelectionKey.OP_CONNECT) != 0) { - // remove OP_CONNECT as otherwise Selector.select(..) will always return without blocking - // See https://github.com/netty/netty/issues/924 - int ops = k.interestOps(); - ops &= ~SelectionKey.OP_CONNECT; - k.interestOps(ops); - - unsafe.finishConnect(); - } } catch (CancelledKeyException ignored) { unsafe.close(unsafe.voidPromise()); }