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 e4a9f055f3
commit e7bfec3b3b
2 changed files with 12 additions and 6 deletions

View File

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

View File

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