Skip to content

Commit

Permalink
common: Support NotYetConnectedException / NotYetBoundException
Browse files Browse the repository at this point in the history
Previously, we were throwing the wrong exceptions when calling
read/write on non-connected/non-bound channels.
  • Loading branch information
kohlschuetter committed Jul 2, 2024
1 parent c532e3a commit fdf8a3a
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,15 @@ public final AFDatagramChannel<A> disconnect() throws IOException {
@Override
public final A receive(ByteBuffer dst) throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
A ret = afSocket.getAFImpl().receive(dst);
complete = true;
return ret;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand All @@ -159,14 +160,15 @@ public final A receive(ByteBuffer dst) throws IOException {
@Override
public final int send(ByteBuffer src, SocketAddress target) throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
int ret = afSocket.getAFImpl().send(src, target);
complete = true;
return ret;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand All @@ -175,14 +177,15 @@ public final int send(ByteBuffer src, SocketAddress target) throws IOException {
@Override
public final int read(ByteBuffer dst) throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
int ret = afSocket.getAFImpl().read(dst, null);
complete = true;
return ret;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand All @@ -200,14 +203,15 @@ public final long read(ByteBuffer[] dsts, int offset, int length) throws IOExcep
@Override
public final int write(ByteBuffer src) throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
int ret = afSocket.getAFImpl().write(src);
complete = true;
return ret;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ public final AFServerSocket<A> socket() {
@Override
public AFSocketChannel<A> accept() throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
AFSocket<A> socket = afSocket.accept1(false);
complete = true;
return socket == null ? null : socket.getChannel();
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ public final boolean isConnectionPending() {
@Override
public final boolean connect(SocketAddress remote) throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
boolean connected = afSocket.connect0(remote, 0);
Expand All @@ -210,7 +210,8 @@ public final boolean connect(SocketAddress remote) throws IOException {
complete = true;
return connected;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand All @@ -225,7 +226,7 @@ public final boolean finishConnect() throws IOException {
}

boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
boolean connected = NativeUnixSocket.finishConnect(afSocket.getFileDescriptor())
Expand All @@ -236,7 +237,8 @@ public final boolean finishConnect() throws IOException {
complete = true;
return connected;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand All @@ -255,14 +257,15 @@ public final A getRemoteSocketAddress() {
@Override
public final int read(ByteBuffer dst) throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
int read = afSocket.getAFImpl().read(dst, null);
complete = true;
return read;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand All @@ -289,14 +292,15 @@ public final long write(ByteBuffer[] srcs, int offset, int length) throws IOExce
@Override
public final int write(ByteBuffer src) throws IOException {
boolean complete = false;
IOException exception = null;
Exception exception = null;
try {
begin();
int written = afSocket.getAFImpl().write(src);
complete = true;
return written;
} catch (IOException e) {
throw (exception = InterruptibleChannelUtil.handleException(this, e)); // NOPMD.PreserveStackTrace
throw InterruptibleChannelUtil.ioExceptionOrThrowRuntimeException( // NOPMD.PreserveStackTrace
(exception = InterruptibleChannelUtil.handleException(this, e)));
} finally {
InterruptibleChannelUtil.endInterruptable(this, this::end, complete, exception);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import java.nio.channels.AsynchronousCloseException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetBoundException;
import java.nio.channels.NotYetConnectedException;
import java.nio.channels.spi.AbstractInterruptibleChannel;

import org.eclipse.jdt.annotation.NonNull;
Expand Down Expand Up @@ -52,7 +54,7 @@ interface EndMethod {
* @throws AsynchronousCloseException on error.
*/
static void endInterruptable(AbstractInterruptibleChannel channel, EndMethod end,
boolean complete, IOException exception) throws AsynchronousCloseException {
boolean complete, Exception exception) throws AsynchronousCloseException {
if (!complete) {
if (exception instanceof ClosedChannelException) {
// we already have caught a valid exception; we don't need to throw one from within "end"
Expand All @@ -78,6 +80,16 @@ private static <T extends Exception> T closeAndThrow(AbstractInterruptibleChanne
return exc;
}

static IOException ioExceptionOrThrowRuntimeException(Exception exception) {
if (exception instanceof IOException) {
return (IOException) exception;
} else if (exception instanceof RuntimeException) {
throw (RuntimeException) exception;
} else {
throw new IllegalStateException(exception);
}
}

/**
* Makes sure that upon an exception that is documented to have the channel be closed the channel
* is indeed closed before throwing that exception. If the exception is also documented to have
Expand All @@ -88,7 +100,13 @@ private static <T extends Exception> T closeAndThrow(AbstractInterruptibleChanne
* @return The exception.
*/
@SuppressWarnings("null")
static IOException handleException(AbstractInterruptibleChannel channel, IOException e) {
static Exception handleException(AbstractInterruptibleChannel channel, IOException e) {
if (e instanceof NotConnectedSocketException) {
return (NotYetConnectedException) new NotYetConnectedException().initCause(e);
} else if (e instanceof NotBoundSocketException) {
return (NotYetBoundException) new NotYetBoundException().initCause(e);
}

if (e instanceof SocketClosedException || e instanceof ClosedChannelException
|| e instanceof BrokenPipeSocketException) {
Thread t = Thread.currentThread();
Expand Down

0 comments on commit fdf8a3a

Please sign in to comment.