8246707: (sc) SocketChannel.read/write throws AsynchronousCloseException on closed channel

This fix addresses an issue where an AsynchronousCloseException was being thrown instead of a ChannelClosedException when SocketChannel.write() is called on a closed SocketChannel.

Reviewed-by: alanb, chegar, dfuchs
This commit is contained in:
Conor Cleary 2020-08-12 12:32:54 +01:00 committed by Patrick Concannon
parent c540da3c4c
commit 831f23ee86
2 changed files with 142 additions and 13 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -324,8 +324,7 @@ class SocketChannelImpl
/**
* Marks the beginning of a read operation that might block.
*
* @throws ClosedChannelException if the channel is closed
* @throws NotYetConnectedException if the channel is not yet connected
* @throws ClosedChannelException if blocking and the channel is closed
*/
private void beginRead(boolean blocking) throws ClosedChannelException {
if (blocking) {
@ -333,12 +332,10 @@ class SocketChannelImpl
begin();
synchronized (stateLock) {
ensureOpenAndConnected();
ensureOpen();
// record thread so it can be signalled if needed
readerThread = NativeThread.current();
}
} else {
ensureOpenAndConnected();
}
}
@ -373,6 +370,7 @@ class SocketChannelImpl
readLock.lock();
try {
ensureOpenAndConnected();
boolean blocking = isBlocking();
int n = 0;
try {
@ -415,6 +413,7 @@ class SocketChannelImpl
readLock.lock();
try {
ensureOpenAndConnected();
boolean blocking = isBlocking();
long n = 0;
try {
@ -452,8 +451,7 @@ class SocketChannelImpl
/**
* Marks the beginning of a write operation that might block.
*
* @throws ClosedChannelException if the channel is closed or output shutdown
* @throws NotYetConnectedException if the channel is not yet connected
* @throws ClosedChannelException if blocking and the channel is closed
*/
private void beginWrite(boolean blocking) throws ClosedChannelException {
if (blocking) {
@ -461,14 +459,12 @@ class SocketChannelImpl
begin();
synchronized (stateLock) {
ensureOpenAndConnected();
ensureOpen();
if (isOutputClosed)
throw new ClosedChannelException();
// record thread so it can be signalled if needed
writerThread = NativeThread.current();
}
} else {
ensureOpenAndConnected();
}
}
@ -496,9 +492,9 @@ class SocketChannelImpl
@Override
public int write(ByteBuffer buf) throws IOException {
Objects.requireNonNull(buf);
writeLock.lock();
try {
ensureOpenAndConnected();
boolean blocking = isBlocking();
int n = 0;
try {
@ -529,6 +525,7 @@ class SocketChannelImpl
writeLock.lock();
try {
ensureOpenAndConnected();
boolean blocking = isBlocking();
long n = 0;
try {
@ -557,6 +554,7 @@ class SocketChannelImpl
int sendOutOfBandData(byte b) throws IOException {
writeLock.lock();
try {
ensureOpenAndConnected();
boolean blocking = isBlocking();
int n = 0;
try {
@ -1177,6 +1175,8 @@ class SocketChannelImpl
readLock.lock();
try {
ensureOpenAndConnected();
// check that channel is configured blocking
if (!isBlocking())
throw new IllegalBlockingModeException();
@ -1254,6 +1254,8 @@ class SocketChannelImpl
writeLock.lock();
try {
ensureOpenAndConnected();
// check that channel is configured blocking
if (!isBlocking())
throw new IllegalBlockingModeException();
@ -1261,8 +1263,8 @@ class SocketChannelImpl
// loop until all bytes have been written
int pos = off;
int end = off + len;
beginWrite(true);
try {
beginWrite(true);
while (pos < end && isOpen()) {
int size = end - pos;
int n = tryWrite(b, pos, size);