Made the AIO transport adhere to Netty thread model strictly

- Fixed data races
- Simplified channel creation using dummy AsyncChannelGroup
This commit is contained in:
Trustin Lee 2012-07-08 00:53:56 +09:00
parent 613834f326
commit cef7dfc02f
12 changed files with 176 additions and 270 deletions

View File

@ -32,8 +32,6 @@ import io.netty.logging.InternalLoggerFactory;
import io.netty.util.internal.DetectionUtil; import io.netty.util.internal.DetectionUtil;
import java.io.IOException; import java.io.IOException;
import java.net.DatagramSocket;
import java.net.Socket;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException; import java.nio.channels.ClosedChannelException;
import java.nio.channels.DatagramChannel; import java.nio.channels.DatagramChannel;
@ -721,7 +719,6 @@ public class SslHandler
"SSLEngine.closeInbound() raised an exception after " + "SSLEngine.closeInbound() raised an exception after " +
"a handshake failure.", e); "a handshake failure.", e);
} }
} }
for (;;) { for (;;) {
@ -757,7 +754,7 @@ public class SslHandler
@Override @Override
public void run() { public void run() {
if (future.setSuccess()) { if (future.setSuccess()) {
logger.debug("close_notify write attempt timed out. Force-closing the connection."); logger.warn("close_notify write attempt timed out. Force-closing the connection.");
ctx.close(ctx.newFuture()); ctx.close(ctx.newFuture());
} }
} }
@ -768,9 +765,10 @@ public class SslHandler
@Override @Override
public void operationComplete(ChannelFuture f) public void operationComplete(ChannelFuture f)
throws Exception { throws Exception {
timeoutFuture.cancel(false); if (timeoutFuture.cancel(false)) {
ctx.close(future); ctx.close(future);
} }
}
}); });
} }

View File

@ -19,7 +19,6 @@ import java.util.concurrent.ThreadFactory;
public abstract class MultithreadEventLoop extends MultithreadEventExecutor implements EventLoop { public abstract class MultithreadEventLoop extends MultithreadEventExecutor implements EventLoop {
protected MultithreadEventLoop(int nThreads, ThreadFactory threadFactory, protected MultithreadEventLoop(int nThreads, ThreadFactory threadFactory,
Object... args) { Object... args) {
super(nThreads, threadFactory, args); super(nThreads, threadFactory, args);

View File

@ -36,15 +36,19 @@ final class LocalChildEventLoop extends SingleThreadEventLoop {
// Waken up by interruptThread() // Waken up by interruptThread()
} }
if (isShutdown() && peekTask() == null) { if (isShutdown()) {
task = pollTask();
if (task == null) {
break; break;
} }
task.run();
}
} }
} }
@Override @Override
protected void wakeup(boolean inEventLoop) { protected void wakeup(boolean inEventLoop) {
if (!inEventLoop) { if (!inEventLoop && isShutdown()) {
interruptThread(); interruptThread();
} }
} }

View File

@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
public abstract class AbstractAioChannel extends AbstractChannel { public abstract class AbstractAioChannel extends AbstractChannel {
protected volatile AsynchronousChannel ch; private final AsynchronousChannel ch;
/** /**
* The future of the current connection attempt. If not null, subsequent * The future of the current connection attempt. If not null, subsequent
@ -39,23 +39,18 @@ public abstract class AbstractAioChannel extends AbstractChannel {
protected ScheduledFuture<?> connectTimeoutFuture; protected ScheduledFuture<?> connectTimeoutFuture;
private ConnectException connectTimeoutException; private ConnectException connectTimeoutException;
protected AbstractAioChannel(Channel parent, Integer id) { protected AbstractAioChannel(Channel parent, Integer id, AsynchronousChannel ch) {
super(parent, id); super(parent, id);
this.ch = ch;
} }
@Override @Override
public InetSocketAddress localAddress() { public InetSocketAddress localAddress() {
if (ch == null) {
return null;
}
return (InetSocketAddress) super.localAddress(); return (InetSocketAddress) super.localAddress();
} }
@Override @Override
public InetSocketAddress remoteAddress() { public InetSocketAddress remoteAddress() {
if (ch == null) {
return null;
}
return (InetSocketAddress) super.remoteAddress(); return (InetSocketAddress) super.remoteAddress();
} }
@ -65,7 +60,7 @@ public abstract class AbstractAioChannel extends AbstractChannel {
@Override @Override
public boolean isOpen() { public boolean isOpen() {
return ch == null || ch.isOpen(); return ch.isOpen();
} }
@Override @Override

View File

@ -36,15 +36,19 @@ final class AioChildEventLoop extends SingleThreadEventLoop {
// Waken up by interruptThread() // Waken up by interruptThread()
} }
if (isShutdown() && peekTask() == null) { if (isShutdown()) {
task = pollTask();
if (task == null) {
break; break;
} }
task.run();
}
} }
} }
@Override @Override
protected void wakeup(boolean inEventLoop) { protected void wakeup(boolean inEventLoop) {
if (!inEventLoop) { if (!inEventLoop && isShutdown()) {
interruptThread(); interruptThread();
} }
} }

View File

@ -37,26 +37,55 @@ abstract class AioCompletionHandler<V, A extends Channel> implements CompletionH
*/ */
protected abstract void failed0(Throwable exc, A channel); protected abstract void failed0(Throwable exc, A channel);
private static final int MAX_STACK_DEPTH = 4;
private static final ThreadLocal<Integer> STACK_DEPTH = new ThreadLocal<Integer>() {
@Override
protected Integer initialValue() {
return 0;
}
};
@Override @Override
public final void completed(final V result, final A channel) { public final void completed(final V result, final A channel) {
if (channel.eventLoop().inEventLoop()) { EventLoop loop = channel.eventLoop();
if (loop.inEventLoop()) {
Integer d = STACK_DEPTH.get();
if (d < MAX_STACK_DEPTH) {
STACK_DEPTH.set(d + 1);
try {
completed0(result, channel); completed0(result, channel);
} else { } finally {
channel.eventLoop().execute(new Runnable() { STACK_DEPTH.set(d);
}
return;
}
}
loop.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
completed0(result, channel); completed0(result, channel);
} }
}); });
} }
}
@Override @Override
public final void failed(final Throwable exc, final A channel) { public final void failed(final Throwable exc, final A channel) {
if (channel.eventLoop().inEventLoop()) { EventLoop loop = channel.eventLoop();
if (loop.inEventLoop()) {
Integer d = STACK_DEPTH.get();
if (d < MAX_STACK_DEPTH) {
STACK_DEPTH.set(d + 1);
try {
failed0(exc, channel); failed0(exc, channel);
} else { } finally {
channel.eventLoop().execute(new Runnable() { STACK_DEPTH.set(d);
}
return;
}
}
loop.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
failed0(exc, channel); failed0(exc, channel);
@ -64,4 +93,3 @@ abstract class AioCompletionHandler<V, A extends Channel> implements CompletionH
}); });
} }
} }
}

View File

@ -0,0 +1,61 @@
package io.netty.channel.socket.aio;
import java.nio.channels.AsynchronousChannelGroup;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.TimeUnit;
final class AioGroup {
static final AsynchronousChannelGroup GROUP;
static {
AsynchronousChannelGroup group;
try {
group = AsynchronousChannelGroup.withThreadPool(new AioGroupExecutor());
} catch (Exception e) {
throw new Error(e);
}
GROUP = group;
}
private AioGroup() {
// Unused
}
static final class AioGroupExecutor extends AbstractExecutorService {
@Override
public void shutdown() {
// Unstoppable
}
@Override
public List<Runnable> shutdownNow() {
return Collections.emptyList();
}
@Override
public boolean isShutdown() {
return false;
}
@Override
public boolean isTerminated() {
return false;
}
@Override
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
Thread.sleep(unit.toMillis(timeout));
return false;
}
@Override
public void execute(Runnable command) {
command.run();
}
}
}

View File

@ -26,7 +26,6 @@ import io.netty.logging.InternalLoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousCloseException; import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.AsynchronousServerSocketChannel; import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.AsynchronousSocketChannel;
@ -39,11 +38,20 @@ public class AioServerSocketChannel extends AbstractAioChannel implements Server
private static final InternalLogger logger = private static final InternalLogger logger =
InternalLoggerFactory.getInstance(AioServerSocketChannel.class); InternalLoggerFactory.getInstance(AioServerSocketChannel.class);
private final AioServerSocketChannelConfig config = new AioServerSocketChannelConfig(); private final AioServerSocketChannelConfig config;
private boolean closed; private boolean closed;
private static AsynchronousServerSocketChannel newSocket() {
try {
return AsynchronousServerSocketChannel.open(AioGroup.GROUP);
} catch (IOException e) {
throw new ChannelException("Failed to open a socket.", e);
}
}
public AioServerSocketChannel() { public AioServerSocketChannel() {
super(null, null); super(null, null, newSocket());
config = new AioServerSocketChannelConfig(javaChannel());
} }
@Override @Override
@ -53,15 +61,7 @@ public class AioServerSocketChannel extends AbstractAioChannel implements Server
@Override @Override
public boolean isActive() { public boolean isActive() {
AsynchronousServerSocketChannel channel = javaChannel(); return javaChannel().isOpen() && localAddress0() != null;
try {
if (channel != null && channel.getLocalAddress() != null) {
return true;
}
} catch (IOException e) {
return true;
}
return false;
} }
@Override @Override
@ -85,9 +85,9 @@ public class AioServerSocketChannel extends AbstractAioChannel implements Server
@Override @Override
protected void doBind(SocketAddress localAddress) throws Exception { protected void doBind(SocketAddress localAddress) throws Exception {
javaChannel().bind(localAddress); AsynchronousServerSocketChannel ch = javaChannel();
javaChannel().accept(this, ACCEPT_HANDLER); ch.bind(localAddress);
ch.accept(this, ACCEPT_HANDLER);
} }
@Override @Override
@ -116,9 +116,6 @@ public class AioServerSocketChannel extends AbstractAioChannel implements Server
@Override @Override
protected Runnable doRegister() throws Exception { protected Runnable doRegister() throws Exception {
ch = AsynchronousServerSocketChannel.open(AsynchronousChannelGroup.withThreadPool(eventLoop()));
config.setChannel(javaChannel());
return null; return null;
} }

View File

@ -33,26 +33,11 @@ import java.util.Map;
final class AioServerSocketChannelConfig extends DefaultChannelConfig final class AioServerSocketChannelConfig extends DefaultChannelConfig
implements ServerSocketChannelConfig { implements ServerSocketChannelConfig {
private volatile AsynchronousServerSocketChannel channel; private final AsynchronousServerSocketChannel channel;
private volatile Integer receiveBufferSize;
private volatile Boolean reuseAddress;
private volatile int backlog = NetworkConstants.SOMAXCONN; private volatile int backlog = NetworkConstants.SOMAXCONN;
void setChannel(AsynchronousServerSocketChannel channel) { AioServerSocketChannelConfig(AsynchronousServerSocketChannel channel) {
if (channel == null) {
throw new NullPointerException("channel");
}
if (this.channel != null) {
throw new IllegalStateException();
}
this.channel = channel; this.channel = channel;
if (receiveBufferSize != null) {
setReceiveBufferSize(receiveBufferSize);
}
if (reuseAddress != null) {
setReuseAddress(reuseAddress);
}
} }
@Override @Override
@ -94,14 +79,6 @@ final class AioServerSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public boolean isReuseAddress() { public boolean isReuseAddress() {
AsynchronousServerSocketChannel channel = this.channel;
if (channel == null) {
if (reuseAddress == null) {
return false;
} else {
return reuseAddress;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_REUSEADDR); return channel.getOption(StandardSocketOptions.SO_REUSEADDR);
} catch (IOException e) { } catch (IOException e) {
@ -111,10 +88,6 @@ final class AioServerSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setReuseAddress(boolean reuseAddress) { public void setReuseAddress(boolean reuseAddress) {
AsynchronousServerSocketChannel channel = this.channel;
if (channel == null) {
this.reuseAddress = reuseAddress;
}
try { try {
channel.setOption(StandardSocketOptions.SO_REUSEADDR, reuseAddress); channel.setOption(StandardSocketOptions.SO_REUSEADDR, reuseAddress);
} catch (IOException e) { } catch (IOException e) {
@ -124,14 +97,6 @@ final class AioServerSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public int getReceiveBufferSize() { public int getReceiveBufferSize() {
AsynchronousServerSocketChannel channel = this.channel;
if (channel == null) {
if (receiveBufferSize == null) {
return 0;
} else {
return receiveBufferSize;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_RCVBUF); return channel.getOption(StandardSocketOptions.SO_RCVBUF);
} catch (IOException e) { } catch (IOException e) {
@ -141,12 +106,6 @@ final class AioServerSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setReceiveBufferSize(int receiveBufferSize) { public void setReceiveBufferSize(int receiveBufferSize) {
AsynchronousServerSocketChannel channel = this.channel;
if (channel == null) {
this.receiveBufferSize = receiveBufferSize;
return;
}
try { try {
channel.setOption(StandardSocketOptions.SO_RCVBUF, receiveBufferSize); channel.setOption(StandardSocketOptions.SO_RCVBUF, receiveBufferSize);
} catch (IOException e) { } catch (IOException e) {

View File

@ -17,6 +17,7 @@ package io.netty.channel.socket.aio;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ChannelBufType; import io.netty.buffer.ChannelBufType;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelMetadata; import io.netty.channel.ChannelMetadata;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
@ -26,12 +27,10 @@ import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousCloseException; import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.ClosedChannelException; import java.nio.channels.ClosedChannelException;
import java.nio.channels.CompletionHandler; import java.nio.channels.CompletionHandler;
import java.nio.channels.NetworkChannel;
public class AioSocketChannel extends AbstractAioChannel implements SocketChannel { public class AioSocketChannel extends AbstractAioChannel implements SocketChannel {
@ -42,29 +41,30 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
private static final CompletionHandler<Integer, AioSocketChannel> READ_HANDLER = new ReadHandler(); private static final CompletionHandler<Integer, AioSocketChannel> READ_HANDLER = new ReadHandler();
private static final CompletionHandler<Integer, AioSocketChannel> WRITE_HANDLER = new WriteHandler(); private static final CompletionHandler<Integer, AioSocketChannel> WRITE_HANDLER = new WriteHandler();
private final AioSocketChannelConfig config = new AioSocketChannelConfig(); private final AioSocketChannelConfig config;
private boolean closed; private boolean closed;
private boolean flushing; private boolean flushing;
public AioSocketChannel() { private static AsynchronousSocketChannel newSocket() {
this(null, null, null); try {
return AsynchronousSocketChannel.open(AioGroup.GROUP);
} catch (IOException e) {
throw new ChannelException("Failed to open a socket.", e);
}
} }
public AioSocketChannel(AioServerSocketChannel parent, Integer id, AsynchronousSocketChannel channel) { public AioSocketChannel() {
super(parent, id); this(null, null, newSocket());
ch = channel;
if (ch != null) {
config.setChannel(channel);
} }
AioSocketChannel(AioServerSocketChannel parent, Integer id, AsynchronousSocketChannel ch) {
super(parent, id, ch);
config = new AioSocketChannelConfig(ch);
} }
@Override @Override
public boolean isActive() { public boolean isActive() {
if (ch == null) { return javaChannel().isOpen() && remoteAddress0() != null;
return false;
}
AsynchronousSocketChannel ch = javaChannel();
return ch.isOpen() && remoteAddress() != null;
} }
@Override @Override
@ -79,7 +79,6 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
@Override @Override
protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress, final ChannelFuture future) { protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress, final ChannelFuture future) {
assert ch != null;
if (localAddress != null) { if (localAddress != null) {
try { try {
javaChannel().bind(localAddress); javaChannel().bind(localAddress);
@ -112,11 +111,10 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
@Override @Override
protected Runnable doRegister() throws Exception { protected Runnable doRegister() throws Exception {
if (ch == null) { if (remoteAddress() == null) {
ch = AsynchronousSocketChannel.open(AsynchronousChannelGroup.withThreadPool(eventLoop()));
config.setChannel((NetworkChannel) ch);
return null; return null;
} else if (remoteAddress() != null) { }
return new Runnable() { return new Runnable() {
@Override @Override
public void run() { public void run() {
@ -124,15 +122,17 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
} }
}; };
} }
return null;
}
/** /**
* Trigger a read from the {@link AioSocketChannel} * Trigger a read from the {@link AioSocketChannel}
*/ */
void read() { void read() {
ByteBuf byteBuf = pipeline().inboundByteBuffer(); ByteBuf byteBuf = pipeline().inboundByteBuffer();
if (!byteBuf.readable()) {
byteBuf.clear();
} else {
expandReadBuffer(byteBuf); expandReadBuffer(byteBuf);
}
// Get a ByteBuffer view on the ByteBuf // Get a ByteBuffer view on the ByteBuf
ByteBuffer buffer = byteBuf.nioBuffer(byteBuf.writerIndex(), byteBuf.writableBytes()); ByteBuffer buffer = byteBuf.nioBuffer(byteBuf.writerIndex(), byteBuf.writableBytes());
javaChannel().read(buffer, this, READ_HANDLER); javaChannel().read(buffer, this, READ_HANDLER);
@ -264,6 +264,7 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
// This is needed as the ByteBuffer and the ByteBuf does not share // This is needed as the ByteBuffer and the ByteBuf does not share
// each others index // each others index
byteBuf.writerIndex(byteBuf.writerIndex() + localReadAmount); byteBuf.writerIndex(byteBuf.writerIndex() + localReadAmount);
expandReadBuffer(byteBuf);
read = true; read = true;
} else if (localReadAmount < 0) { } else if (localReadAmount < 0) {
@ -338,11 +339,6 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
@Override @Override
public AioSocketChannelConfig config() { public AioSocketChannelConfig config() {
if (config == null) {
throw new IllegalStateException("Channel not open yet");
}
return config; return config;
} }
} }

View File

@ -32,48 +32,17 @@ import java.util.Map;
final class AioSocketChannelConfig extends DefaultChannelConfig final class AioSocketChannelConfig extends DefaultChannelConfig
implements SocketChannelConfig { implements SocketChannelConfig {
private volatile NetworkChannel channel; private final NetworkChannel channel;
private volatile Integer receiveBufferSize;
private volatile Integer sendBufferSize;
private volatile Boolean tcpNoDelay;
private volatile Boolean keepAlive;
private volatile Boolean reuseAddress;
private volatile Integer soLinger;
private volatile Integer trafficClass;
/** /**
* Creates a new instance. * Creates a new instance.
*/ */
void setChannel(NetworkChannel channel) { AioSocketChannelConfig(NetworkChannel channel) {
if (channel == null) { if (channel == null) {
throw new NullPointerException("channel"); throw new NullPointerException("channel");
} }
if (this.channel != null) {
throw new IllegalStateException();
}
this.channel = channel;
if (receiveBufferSize != null) { this.channel = channel;
setReceiveBufferSize(receiveBufferSize);
}
if (sendBufferSize != null) {
setSendBufferSize(sendBufferSize);
}
if (reuseAddress != null) {
setReuseAddress(reuseAddress);
}
if (tcpNoDelay != null) {
setTcpNoDelay(tcpNoDelay);
}
if (keepAlive != null) {
setKeepAlive(keepAlive);
}
if (soLinger != null) {
setSoLinger(soLinger);
}
if (trafficClass != null) {
setTrafficClass(trafficClass);
}
} }
@Override @Override
@ -137,15 +106,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public int getReceiveBufferSize() { public int getReceiveBufferSize() {
NetworkChannel channel = this.channel;
if (channel == null) {
if (receiveBufferSize == null) {
return 0;
} else {
return receiveBufferSize;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_RCVBUF); return channel.getOption(StandardSocketOptions.SO_RCVBUF);
} catch (IOException e) { } catch (IOException e) {
@ -155,15 +115,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public int getSendBufferSize() { public int getSendBufferSize() {
NetworkChannel channel = this.channel;
if (channel == null) {
if (sendBufferSize == null) {
return 0;
} else {
return sendBufferSize;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_SNDBUF); return channel.getOption(StandardSocketOptions.SO_SNDBUF);
} catch (IOException e) { } catch (IOException e) {
@ -173,15 +124,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public int getSoLinger() { public int getSoLinger() {
NetworkChannel channel = this.channel;
if (channel == null) {
if (soLinger == null) {
return 1;
} else {
return soLinger;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_LINGER); return channel.getOption(StandardSocketOptions.SO_LINGER);
} catch (IOException e) { } catch (IOException e) {
@ -191,15 +133,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public int getTrafficClass() { public int getTrafficClass() {
NetworkChannel channel = this.channel;
if (channel == null) {
if (trafficClass == null) {
return 0;
} else {
return trafficClass;
}
}
try { try {
return channel.getOption(StandardSocketOptions.IP_TOS); return channel.getOption(StandardSocketOptions.IP_TOS);
} catch (IOException e) { } catch (IOException e) {
@ -209,15 +142,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public boolean isKeepAlive() { public boolean isKeepAlive() {
NetworkChannel channel = this.channel;
if (channel == null) {
if (keepAlive == null) {
return false;
} else {
return keepAlive;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_KEEPALIVE); return channel.getOption(StandardSocketOptions.SO_KEEPALIVE);
} catch (IOException e) { } catch (IOException e) {
@ -227,15 +151,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public boolean isReuseAddress() { public boolean isReuseAddress() {
NetworkChannel channel = this.channel;
if (channel == null) {
if (reuseAddress == null) {
return false;
} else {
return reuseAddress;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_REUSEADDR); return channel.getOption(StandardSocketOptions.SO_REUSEADDR);
} catch (IOException e) { } catch (IOException e) {
@ -245,15 +160,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public boolean isTcpNoDelay() { public boolean isTcpNoDelay() {
NetworkChannel channel = this.channel;
if (channel == null) {
if (tcpNoDelay == null) {
return false;
} else {
return tcpNoDelay;
}
}
try { try {
return channel.getOption(StandardSocketOptions.SO_REUSEADDR); return channel.getOption(StandardSocketOptions.SO_REUSEADDR);
} catch (IOException e) { } catch (IOException e) {
@ -263,12 +169,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setKeepAlive(boolean keepAlive) { public void setKeepAlive(boolean keepAlive) {
NetworkChannel channel = this.channel;
if (channel == null) {
this.keepAlive = keepAlive;
return;
}
try { try {
channel.setOption(StandardSocketOptions.SO_KEEPALIVE, keepAlive); channel.setOption(StandardSocketOptions.SO_KEEPALIVE, keepAlive);
} catch (IOException e) { } catch (IOException e) {
@ -284,12 +184,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setReceiveBufferSize(int receiveBufferSize) { public void setReceiveBufferSize(int receiveBufferSize) {
NetworkChannel channel = this.channel;
if (channel == null) {
this.receiveBufferSize = receiveBufferSize;
return;
}
try { try {
channel.setOption(StandardSocketOptions.SO_RCVBUF, receiveBufferSize); channel.setOption(StandardSocketOptions.SO_RCVBUF, receiveBufferSize);
} catch (IOException e) { } catch (IOException e) {
@ -299,12 +193,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setReuseAddress(boolean reuseAddress) { public void setReuseAddress(boolean reuseAddress) {
NetworkChannel channel = this.channel;
if (channel == null) {
this.reuseAddress = reuseAddress;
return;
}
try { try {
channel.setOption(StandardSocketOptions.SO_REUSEADDR, reuseAddress); channel.setOption(StandardSocketOptions.SO_REUSEADDR, reuseAddress);
} catch (IOException e) { } catch (IOException e) {
@ -314,12 +202,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setSendBufferSize(int sendBufferSize) { public void setSendBufferSize(int sendBufferSize) {
NetworkChannel channel = this.channel;
if (channel == null) {
this.sendBufferSize = sendBufferSize;
return;
}
try { try {
channel.setOption(StandardSocketOptions.SO_SNDBUF, sendBufferSize); channel.setOption(StandardSocketOptions.SO_SNDBUF, sendBufferSize);
} catch (IOException e) { } catch (IOException e) {
@ -329,12 +211,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setSoLinger(int soLinger) { public void setSoLinger(int soLinger) {
NetworkChannel channel = this.channel;
if (channel == null) {
this.soLinger = soLinger;
return;
}
try { try {
channel.setOption(StandardSocketOptions.SO_LINGER, soLinger); channel.setOption(StandardSocketOptions.SO_LINGER, soLinger);
} catch (IOException e) { } catch (IOException e) {
@ -344,12 +220,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setTcpNoDelay(boolean tcpNoDelay) { public void setTcpNoDelay(boolean tcpNoDelay) {
NetworkChannel channel = this.channel;
if (channel == null) {
this.tcpNoDelay = tcpNoDelay;
return;
}
try { try {
channel.setOption(StandardSocketOptions.TCP_NODELAY, tcpNoDelay); channel.setOption(StandardSocketOptions.TCP_NODELAY, tcpNoDelay);
} catch (IOException e) { } catch (IOException e) {
@ -359,11 +229,6 @@ final class AioSocketChannelConfig extends DefaultChannelConfig
@Override @Override
public void setTrafficClass(int trafficClass) { public void setTrafficClass(int trafficClass) {
NetworkChannel channel = this.channel;
if (channel == null) {
this.trafficClass = trafficClass;
}
try { try {
channel.setOption(StandardSocketOptions.IP_TOS, trafficClass); channel.setOption(StandardSocketOptions.IP_TOS, trafficClass);
} catch (IOException e) { } catch (IOException e) {

View File

@ -290,7 +290,7 @@ public class SingleThreadEventLoopTest {
@Override @Override
protected void wakeup(boolean inEventLoop) { protected void wakeup(boolean inEventLoop) {
if (!inEventLoop) { if (!inEventLoop && isShutdown()) {
interruptThread(); interruptThread();
} }
} }