Epoll Shutdown Input Exception Handling

Motivation:
If ChannelOption.ALLOW_HALF_CLOSURE is true and the shutdown input operation fails we should not propagate this exception, and instead consider this socket's read as half closed.

Modifications:
- AbstractEpollChannel.shutdownInput should not propagate exceptions when attempting to shutdown the input, but instead should just close the socket

Result:
Users expecting a ChannelInputShutdownEvent will get this event even if the socket is already shutdown, and the shutdown operation fails.
This commit is contained in:
Scott Mitchell 2015-11-12 18:29:02 -08:00 committed by Norman Maurer
parent 2a65ae256e
commit b640de2d94
2 changed files with 12 additions and 6 deletions

View File

@ -366,8 +366,10 @@ abstract class AbstractEpollChannel extends AbstractChannel implements UnixChann
fd().shutdown(true, false); fd().shutdown(true, false);
clearEpollIn0(); clearEpollIn0();
pipeline().fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE); pipeline().fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
} catch (IOException e) { } catch (IOException ignored) {
pipeline().fireExceptionCaught(e); // We attempted to shutdown and failed, which means the input has already effectively been
// shutdown.
pipeline().fireUserEventTriggered(ChannelInputShutdownEvent.INSTANCE);
close(voidPromise()); close(voidPromise());
} }
} else { } else {

View File

@ -49,19 +49,23 @@ public final class Socket extends FileDescriptor {
super(fd); super(fd);
} }
public void shutdown() throws IOException {
shutdown(!inputShutdown, !outputShutdown);
}
public void shutdown(boolean read, boolean write) throws IOException { public void shutdown(boolean read, boolean write) throws IOException {
inputShutdown = read || inputShutdown; inputShutdown = read || inputShutdown;
outputShutdown = write || outputShutdown; outputShutdown = write || outputShutdown;
shutdown0(read, write);
}
private void shutdown0(boolean read, boolean write) throws IOException {
int res = shutdown(intValue(), read, write); int res = shutdown(intValue(), read, write);
if (res < 0) { if (res < 0) {
ioResult("shutdown", res, CONNECTION_NOT_CONNECTED_SHUTDOWN_EXCEPTION); ioResult("shutdown", res, CONNECTION_NOT_CONNECTED_SHUTDOWN_EXCEPTION);
} }
} }
public void shutdown() throws IOException {
shutdown(true, true);
}
public boolean isShutdown() { public boolean isShutdown() {
return isInputShutdown() && isOutputShutdown(); return isInputShutdown() && isOutputShutdown();
} }