8203059: (so) Closing a socket channel registered with Selector and with SO_LINGER set to 0 does not reset connection

Reviewed-by: chegar
This commit is contained in:
Alan Bateman 2018-05-15 09:33:02 +01:00
parent e155b21fce
commit d64c38aab2
2 changed files with 133 additions and 3 deletions

View file

@ -867,11 +867,22 @@ class SocketChannelImpl
// set state to ST_KILLPENDING
synchronized (stateLock) {
assert state == ST_CLOSING;
// if connected, and the channel is registered with a Selector, we
// shutdown the output so that the peer reads EOF
// if connected and the channel is registered with a Selector then
// shutdown the output if possible so that the peer reads EOF. If
// SO_LINGER is enabled and set to a non-zero value then it needs to
// be disabled so that the Selector does not wait when it closes
// the socket.
if (connected && isRegistered()) {
try {
Net.shutdown(fd, Net.SHUT_WR);
SocketOption<Integer> opt = StandardSocketOptions.SO_LINGER;
int interval = (int) Net.getSocketOption(fd, Net.UNSPEC, opt);
if (interval != 0) {
if (interval > 0) {
// disable SO_LINGER
Net.setSocketOption(fd, Net.UNSPEC, opt, -1);
}
Net.shutdown(fd, Net.SHUT_WR);
}
} catch (IOException ignore) { }
}
state = ST_KILLPENDING;