diff --git a/main/poll/poll_backend_epoll.c b/main/poll/poll_backend_epoll.c index 394b0dc52446..0dca54a96eec 100644 --- a/main/poll/poll_backend_epoll.c +++ b/main/poll/poll_backend_epoll.c @@ -18,6 +18,11 @@ #include +#ifdef HAVE_EPOLL_PWAIT2 +/* Cleared when the running kernel returns ENOSYS */ +static zend_atomic_bool epoll_pwait2_available = ZEND_ATOMIC_BOOL_INITIALIZER(true); +#endif + typedef struct epoll_backend_data { int epoll_fd; struct epoll_event *events; @@ -180,13 +185,21 @@ static int epoll_backend_wait( backend_data->events_capacity = max_events; } - int nfds; + int nfds = 0; #ifdef HAVE_EPOLL_PWAIT2 - nfds = epoll_pwait2(backend_data->epoll_fd, backend_data->events, max_events, timeout, NULL); -#else - int timeout_ms = php_poll_timespec_to_ms(timeout); - nfds = epoll_wait(backend_data->epoll_fd, backend_data->events, max_events, timeout_ms); + if (EXPECTED(zend_atomic_bool_load_ex(&epoll_pwait2_available))) { + nfds = epoll_pwait2( + backend_data->epoll_fd, backend_data->events, max_events, timeout, NULL); + if (UNEXPECTED(nfds < 0 && (errno == ENOSYS || errno == ENOTSUP))) { + zend_atomic_bool_store_ex(&epoll_pwait2_available, false); + } + } + if (UNEXPECTED(!zend_atomic_bool_load_ex(&epoll_pwait2_available))) #endif + { + int timeout_ms = php_poll_timespec_to_ms(timeout); + nfds = epoll_wait(backend_data->epoll_fd, backend_data->events, max_events, timeout_ms); + } if (nfds > 0) { for (int i = 0; i < nfds; i++) {