Skip to content

Commit

Permalink
Check if epoll_pwait2 is implemented (netty#12345)
Browse files Browse the repository at this point in the history
Motivation:

Its possible that while there is an epoll_pwait2(...) system call it is not implemented and so fail with ENOSYS.

Modifications:

Check if we can actually use epoll_pwait2(...) and it not fails due not implemented.

Result:

Fixes netty#12343
  • Loading branch information
normanmaurer authored and franz1981 committed Aug 22, 2022
1 parent 9fc40d8 commit 18d31e2
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions transport-native-epoll/src/main/c/netty_epoll_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ static jfieldID packetCountFieldId = NULL;

static const char* staticPackagePrefix = NULL;
static int register_unix_called = 0;
static int epoll_pwait2_supported = 0;

// util methods
static int getSysctlValue(const char * property, int* returnValue) {
Expand Down Expand Up @@ -267,8 +268,8 @@ static jlong netty_epoll_native_epollWait0(JNIEnv* env, jclass clazz, jint efd,
// Let's try to reduce the syscalls as much as possible as timerfd_settime(...) can be expensive:
// See https://github.com/netty/netty/issues/11695

if (epoll_pwait2) {
// We have epoll_pwait2(...), this means we can just pass in the itimerspec directly and not need an
if (epoll_pwait2_supported == 1) {
// We have epoll_pwait2(...) and it is supported, this means we can just pass in the itimerspec directly and not need an
// extra syscall even for very small timeouts.
struct timespec ts = { tvSec, tvNsec };
struct epoll_event *ev = (struct epoll_event*) (intptr_t) address;
Expand Down Expand Up @@ -807,6 +808,24 @@ static jint netty_epoll_native_JNI_OnLoad(JNIEnv* env, const char* packagePrefix
ret = NETTY_JNI_UTIL_JNI_VERSION;

staticPackagePrefix = packagePrefix;

// Check if there is an epoll_pwait2 system call and also if it works. One some systems it might be there
// but actually is not implemented and so fail with ENOSYS.
// See https://github.com/netty/netty/issues/12343
if (epoll_pwait2) {
int efd = epoll_create(1);
if (efd != -1) {
struct timespec ts = { 0, 0 };
struct epoll_event ev;
do {
if (epoll_pwait2(efd, &ev, 1, &ts, NULL) != -1) {
epoll_pwait2_supported = 1;
break;
}
} while(errno == EINTR);
close(efd);
}
}
done:

netty_jni_util_free_dynamic_methods_table(dynamicMethods, fixed_method_table_size, dynamicMethodsTableSize());
Expand Down

0 comments on commit 18d31e2

Please sign in to comment.