From 340287f377e48159b91d60f6bec84dcc98316192 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Fri, 6 Feb 2015 07:34:54 +0100 Subject: [PATCH] Add workaround for bug in older linux kernels handling epoll_wait(...) Motivation: Older linux kernels have problems handling a large value for epoll_wait(...) and so wait for ever. Modifications: Adjust timeout on the fly if a too big value is passed in. Result: Correctly works also on older kernels. --- .../src/main/c/io_netty_channel_epoll_Native.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) 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 0cd6521a5b..9a219f240c 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 @@ -33,6 +33,17 @@ #include #include "io_netty_channel_epoll_Native.h" + +/** + * On older Linux kernels, epoll can't handle timeout + * values bigger than (LONG_MAX - 999ULL)/HZ. + * + * See: + * - https://github.com/libevent/libevent/blob/master/epoll.c#L138 + * - http://cvs.schmorp.de/libev/ev_epoll.c?revision=1.68&view=markup + */ +#define MAX_EPOLL_TIMEOUT_MSEC (35*60*1000) + // optional extern int accept4(int sockFd, struct sockaddr* addr, socklen_t* addrlen, int flags) __attribute__((weak)); extern int epoll_create1(int flags) __attribute__((weak)); @@ -617,6 +628,11 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_epollWait0(JNIEnv* env struct epoll_event *ev = (struct epoll_event*) address; int ready; int err; + + if (timeout > MAX_EPOLL_TIMEOUT_MSEC) { + // Workaround for bug in older linux kernels that can not handle bigger timeout then MAX_EPOLL_TIMEOUT_MSEC. + timeout = MAX_EPOLL_TIMEOUT_MSEC; + } do { ready = epoll_wait(efd, ev, len, timeout); // was interrupted try again. @@ -1500,4 +1516,4 @@ JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_sizeofEpollEvent(JNIEn JNIEXPORT jint JNICALL Java_io_netty_channel_epoll_Native_offsetofEpollData(JNIEnv* env, jclass clazz) { return offsetof(struct epoll_event, data); -} \ No newline at end of file +}