From c4f2019d9140f5d95fdba0ee70d3846a6199361f Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Wed, 30 Sep 2026 17:08:50 +0200 Subject: [PATCH] Load the epoll_pwait2 availability flag once per wait The fallback added in #23825 tested the atomic flag twice on every wait, since the compiler cannot assume it did not change in between, and marked the epoll_wait() path unexpected although it is taken on every wait once the kernel has answered ENOSYS. The two calls are now the branches of one if/else with a goto from the ENOSYS case into the fallback branch, and the branch hints are gone. --- main/poll/poll_backend_epoll.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/main/poll/poll_backend_epoll.c b/main/poll/poll_backend_epoll.c index 85660a9322fe..2cf0cec75700 100644 --- a/main/poll/poll_backend_epoll.c +++ b/main/poll/poll_backend_epoll.c @@ -191,21 +191,24 @@ static int epoll_backend_wait( backend_data->events_capacity = max_events; } - int nfds = 0; + int nfds; #ifdef HAVE_EPOLL_PWAIT2 - if (EXPECTED(zend_atomic_bool_load_ex(&epoll_pwait2_available))) { + if (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))) { + if (nfds < 0 && (errno == ENOSYS || errno == ENOTSUP)) { zend_atomic_bool_store_ex(&epoll_pwait2_available, false); + goto epoll_wait_fallback; } + } else { +epoll_wait_fallback: + nfds = epoll_wait(backend_data->epoll_fd, backend_data->events, max_events, + php_poll_timespec_to_ms(timeout)); } - if (UNEXPECTED(!zend_atomic_bool_load_ex(&epoll_pwait2_available))) +#else + nfds = epoll_wait(backend_data->epoll_fd, backend_data->events, max_events, + php_poll_timespec_to_ms(timeout)); #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++) {