Fix a bug in shutdownOutput() implementations where wrong ChannelFuture is notified

This commit is contained in:
Trustin Lee 2012-08-30 16:38:08 +09:00
parent 68e86d8667
commit a1e8dad4ad
4 changed files with 38 additions and 26 deletions

View File

@ -57,7 +57,7 @@ public class SocketShutdownOutputBySelfTest extends AbstractClientSocketTest {
assertFalse(h.ch.isOutputShutdown()); assertFalse(h.ch.isOutputShutdown());
// Make the connection half-closed and ensure read() returns -1. // Make the connection half-closed and ensure read() returns -1.
ch.shutdownOutput(); ch.shutdownOutput().sync();
assertEquals(-1, s.getInputStream().read()); assertEquals(-1, s.getInputStream().read());
assertTrue(h.ch.isOpen()); assertTrue(h.ch.isOpen());

View File

@ -110,27 +110,31 @@ public class AioSocketChannel extends AbstractAioChannel implements SocketChanne
@Override @Override
public ChannelFuture shutdownOutput() { public ChannelFuture shutdownOutput() {
ChannelFuture future = newFuture(); final ChannelFuture future = newFuture();
EventLoop loop = eventLoop(); EventLoop loop = eventLoop();
if (loop.inEventLoop()) { if (loop.inEventLoop()) {
try { shutdownOutput(future);
javaChannel().shutdownOutput();
outputShutdown = true;
future.setSuccess();
} catch (Throwable t) {
future.setFailure(t);
}
} else { } else {
loop.execute(new Runnable() { loop.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
shutdownOutput(); shutdownOutput(future);
} }
}); });
} }
return future; return future;
} }
private void shutdownOutput(ChannelFuture future) {
try {
javaChannel().shutdownOutput();
outputShutdown = true;
future.setSuccess();
} catch (Throwable t) {
future.setFailure(t);
}
}
@Override @Override
protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress, final ChannelFuture future) { protected void doConnect(SocketAddress remoteAddress, SocketAddress localAddress, final ChannelFuture future) {
if (localAddress != null) { if (localAddress != null) {

View File

@ -110,26 +110,30 @@ public class NioSocketChannel extends AbstractNioByteChannel implements io.netty
@Override @Override
public ChannelFuture shutdownOutput() { public ChannelFuture shutdownOutput() {
ChannelFuture future = newFuture(); final ChannelFuture future = newFuture();
EventLoop loop = eventLoop(); EventLoop loop = eventLoop();
if (loop.inEventLoop()) { if (loop.inEventLoop()) {
try { shutdownOutput(future);
javaChannel().socket().shutdownOutput();
future.setSuccess();
} catch (Throwable t) {
future.setFailure(t);
}
} else { } else {
loop.execute(new Runnable() { loop.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
shutdownOutput(); shutdownOutput(future);
} }
}); });
} }
return future; return future;
} }
private void shutdownOutput(ChannelFuture future) {
try {
javaChannel().socket().shutdownOutput();
future.setSuccess();
} catch (Throwable t) {
future.setFailure(t);
}
}
@Override @Override
protected SocketAddress localAddress0() { protected SocketAddress localAddress0() {
return javaChannel().socket().getLocalSocketAddress(); return javaChannel().socket().getLocalSocketAddress();

View File

@ -115,26 +115,30 @@ public class OioSocketChannel extends AbstractOioByteChannel
@Override @Override
public ChannelFuture shutdownOutput() { public ChannelFuture shutdownOutput() {
ChannelFuture future = newFuture(); final ChannelFuture future = newFuture();
EventLoop loop = eventLoop(); EventLoop loop = eventLoop();
if (loop.inEventLoop()) { if (loop.inEventLoop()) {
try { shutdownOutput(future);
socket.shutdownOutput();
future.setSuccess();
} catch (Throwable t) {
future.setFailure(t);
}
} else { } else {
loop.execute(new Runnable() { loop.execute(new Runnable() {
@Override @Override
public void run() { public void run() {
shutdownOutput(); shutdownOutput(future);
} }
}); });
} }
return future; return future;
} }
private void shutdownOutput(ChannelFuture future) {
try {
socket.shutdownOutput();
future.setSuccess();
} catch (Throwable t) {
future.setFailure(t);
}
}
@Override @Override
protected SocketAddress localAddress0() { protected SocketAddress localAddress0() {
return socket.getLocalSocketAddress(); return socket.getLocalSocketAddress();