Fix race-condition when closing a NioSocketChannel or EpollSocketChannel
Motivation: Fix a race-condition when closing NioSocketChannel or EpollSocketChannel while try to detect if a close executor should be used and the underlying socket was already closed. This could lead to an exception that then leave the channel / in an invalid state and so could lead to side-effects like heavy CPU usage. Modifications: Catch possible socket exception while try to get the SO_LINGER options from the underlying socket. Result: No more race-condition when closing the channel is possible with bad side-effects.
This commit is contained in:
parent
4978266d52
commit
0ec34b5f76
@ -219,10 +219,16 @@ public final class EpollSocketChannel extends AbstractEpollStreamChannel impleme
|
||||
private final class EpollSocketChannelUnsafe extends EpollStreamUnsafe {
|
||||
@Override
|
||||
protected Executor closeExecutor() {
|
||||
// Check isOpen() first as otherwise it will throw a RuntimeException
|
||||
// when call getSoLinger() as the fd is not valid anymore.
|
||||
if (isOpen() && config().getSoLinger() > 0) {
|
||||
return GlobalEventExecutor.INSTANCE;
|
||||
try {
|
||||
// Check isOpen() first as otherwise it will throw a RuntimeException
|
||||
// when call getSoLinger() as the fd is not valid anymore.
|
||||
if (isOpen() && config().getSoLinger() > 0) {
|
||||
return GlobalEventExecutor.INSTANCE;
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
// Ignore the error as the underlying channel may be closed in the meantime and so
|
||||
// getSoLinger() may produce an exception. In this case we just return null.
|
||||
// See https://github.com/netty/netty/issues/4449
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.SocketChannel;
|
||||
@ -336,8 +337,14 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
|
||||
private final class NioSocketChannelUnsafe extends NioByteUnsafe {
|
||||
@Override
|
||||
protected Executor closeExecutor() {
|
||||
if (javaChannel().isOpen() && config().getSoLinger() > 0) {
|
||||
return GlobalEventExecutor.INSTANCE;
|
||||
try {
|
||||
if (javaChannel().isOpen() && config().getSoLinger() > 0) {
|
||||
return GlobalEventExecutor.INSTANCE;
|
||||
}
|
||||
} catch (Throwable ignore) {
|
||||
// Ignore the error as the underlying channel may be closed in the meantime and so
|
||||
// getSoLinger() may produce an exception. In this case we just return null.
|
||||
// See https://github.com/netty/netty/issues/4449
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user