From c3f7a71a735f0df6188404aa87447735d11673c9 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Thu, 19 Feb 2015 15:06:26 +0100 Subject: [PATCH] [#3438] Throw pre-instanced IOException on connection reset Motivation: In the native transport we should throw a pre-instanced IOException on connection reset while reading. Modifications: Correctly throw pre-instanced IOException when ECONNRESET is received Result: Less overhead on connection reset --- .../main/c/io_netty_channel_epoll_Native.c | 4 +++ .../main/c/io_netty_channel_epoll_Native.h | 1 + .../java/io/netty/channel/epoll/Native.java | 31 +++++++++++++------ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.c b/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.c index 89875b5d0b..24231c1443 100644 --- a/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.c +++ b/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.c @@ -1347,6 +1347,10 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_errnoEPIPE(JNIEnv* env return EPIPE; } +JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_errnoECONNRESET(JNIEnv* env, jclass clazz) { + return ECONNRESET; +} + JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_errnoEAGAIN(JNIEnv* env, jclass clazz) { return EAGAIN; } diff --git a/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.h b/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.h index bae39db303..a16c69199d 100644 --- a/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.h +++ b/transport-native-epoll/src/main/c/io_netty_channel_epoll_Native.h @@ -108,6 +108,7 @@ jboolean Java_io_netty_channel_epoll_Native_isSupportingSendmmsg(JNIEnv* env, jc jint Java_io_netty_channel_epoll_Native_errnoEBADF(JNIEnv* env, jclass clazz); jint Java_io_netty_channel_epoll_Native_errnoEPIPE(JNIEnv* env, jclass clazz); +jint Java_io_netty_channel_epoll_Native_errnoECONNRESET(JNIEnv* env, jclass clazz); jint Java_io_netty_channel_epoll_Native_errnoEAGAIN(JNIEnv* env, jclass clazz); jint Java_io_netty_channel_epoll_Native_errnoEWOULDBLOCK(JNIEnv* env, jclass clazz); jint Java_io_netty_channel_epoll_Native_errnoEINPROGRESS(JNIEnv* env, jclass clazz); diff --git a/transport-native-epoll/src/main/java/io/netty/channel/epoll/Native.java b/transport-native-epoll/src/main/java/io/netty/channel/epoll/Native.java index daaeda8739..7c4794af3d 100644 --- a/transport-native-epoll/src/main/java/io/netty/channel/epoll/Native.java +++ b/transport-native-epoll/src/main/java/io/netty/channel/epoll/Native.java @@ -65,6 +65,7 @@ final class Native { // As all our JNI methods return -errno on error we need to compare with the negative errno codes. private static final int ERRNO_EBADF_NEGATIVE = -errnoEBADF(); private static final int ERRNO_EPIPE_NEGATIVE = -errnoEPIPE(); + private static final int ERRNO_ECONNRESET_NEGATIVE = -errnoECONNRESET(); private static final int ERRNO_EAGAIN_NEGATIVE = -errnoEAGAIN(); private static final int ERRNO_EWOULDBLOCK_NEGATIVE = -errnoEWOULDBLOCK(); private static final int ERRNO_EINPROGRESS_NEGATIVE = -errnoEINPROGRESS(); @@ -94,19 +95,27 @@ final class Native { // This is ok as strerror returns 'Unknown error i' when the message is not known. ERRORS[i] = strError(i); } - CONNECTION_RESET_EXCEPTION_WRITE = newConnectionResetException("write"); - CONNECTION_RESET_EXCEPTION_WRITEV = newConnectionResetException("writev"); - CONNECTION_RESET_EXCEPTION_READ = newConnectionResetException("read"); - CONNECTION_RESET_EXCEPTION_SENDFILE = newConnectionResetException("sendfile"); - CONNECTION_RESET_EXCEPTION_SENDTO = newConnectionResetException("sendto"); - CONNECTION_RESET_EXCEPTION_SENDMSG = newConnectionResetException("sendmsg"); - CONNECTION_RESET_EXCEPTION_SENDMMSG = newConnectionResetException("sendmmsg"); + + CONNECTION_RESET_EXCEPTION_READ = newConnectionResetException("syscall:read(...)", + ERRNO_ECONNRESET_NEGATIVE); + CONNECTION_RESET_EXCEPTION_WRITE = newConnectionResetException("syscall:write(...)", + ERRNO_EPIPE_NEGATIVE); + CONNECTION_RESET_EXCEPTION_WRITEV = newConnectionResetException("syscall:writev(...)", + ERRNO_EPIPE_NEGATIVE); + CONNECTION_RESET_EXCEPTION_SENDFILE = newConnectionResetException("syscall:sendfile(...)", + ERRNO_EPIPE_NEGATIVE); + CONNECTION_RESET_EXCEPTION_SENDTO = newConnectionResetException("syscall:sendto(...)", + ERRNO_EPIPE_NEGATIVE); + CONNECTION_RESET_EXCEPTION_SENDMSG = newConnectionResetException("syscall:sendmsg(...)", + ERRNO_EPIPE_NEGATIVE); + CONNECTION_RESET_EXCEPTION_SENDMMSG = newConnectionResetException("syscall:sendmmsg(...)", + ERRNO_EPIPE_NEGATIVE); CLOSED_CHANNEL_EXCEPTION = new ClosedChannelException(); CLOSED_CHANNEL_EXCEPTION.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); } - private static IOException newConnectionResetException(String method) { - IOException exception = newIOException(method, ERRNO_EPIPE_NEGATIVE); + private static IOException newConnectionResetException(String method, int errnoNegative) { + IOException exception = newIOException(method, errnoNegative); exception.setStackTrace(EmptyArrays.EMPTY_STACK_TRACE); return exception; } @@ -120,7 +129,7 @@ final class Native { if (err == ERRNO_EAGAIN_NEGATIVE || err == ERRNO_EWOULDBLOCK_NEGATIVE) { return 0; } - if (err == ERRNO_EPIPE_NEGATIVE) { + if (err == ERRNO_EPIPE_NEGATIVE || err == ERRNO_ECONNRESET_NEGATIVE) { throw resetCause; } if (err == ERRNO_EBADF_NEGATIVE) { @@ -151,6 +160,8 @@ final class Native { private static native int errnoEBADF(); private static native int errnoEPIPE(); + private static native int errnoECONNRESET(); + private static native int errnoEAGAIN(); private static native int errnoEWOULDBLOCK(); private static native int errnoEINPROGRESS();