diff --git a/CMakeLists.txt b/CMakeLists.txt index d7e5d3b409..9e19336771 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1151,7 +1151,7 @@ if(SDL_LIBC) check_symbol_exists(sysctlbyname "sys/types.h;sys/sysctl.h" HAVE_SYSCTLBYNAME) check_symbol_exists(getauxval "sys/auxv.h" HAVE_GETAUXVAL) check_symbol_exists(elf_aux_info "sys/auxv.h" HAVE_ELF_AUX_INFO) - check_symbol_exists(poll "poll.h" HAVE_POLL) + check_symbol_exists(ppoll "poll.h" HAVE_PPOLL) check_symbol_exists(memfd_create "sys/mman.h" HAVE_MEMFD_CREATE) check_symbol_exists(posix_fallocate "fcntl.h" HAVE_POSIX_FALLOCATE) check_symbol_exists(posix_spawn_file_actions_addchdir "spawn.h" HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR) diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake index b4e721ca6b..36d642e705 100644 --- a/include/build_config/SDL_build_config.h.cmake +++ b/include/build_config/SDL_build_config.h.cmake @@ -199,7 +199,7 @@ #cmakedefine HAVE_SEM_TIMEDWAIT 1 #cmakedefine HAVE_GETAUXVAL 1 #cmakedefine HAVE_ELF_AUX_INFO 1 -#cmakedefine HAVE_POLL 1 +#cmakedefine HAVE_PPOLL 1 #cmakedefine HAVE__EXIT 1 #endif /* HAVE_LIBC */ diff --git a/src/core/unix/SDL_poll.c b/src/core/unix/SDL_poll.c index 572ed5a65b..d84a217863 100644 --- a/src/core/unix/SDL_poll.c +++ b/src/core/unix/SDL_poll.c @@ -23,15 +23,13 @@ #include "SDL_poll.h" -#ifdef HAVE_POLL #include -#else -#include -#include -#include -#endif #include +#ifdef HAVE_PPOLL +#include +#endif + int SDL_IOReady(int fd, int flags, Sint64 timeoutNS) { int result; @@ -40,9 +38,7 @@ int SDL_IOReady(int fd, int flags, Sint64 timeoutNS) // Note: We don't bother to account for elapsed time if we get EINTR do { -#ifdef HAVE_POLL struct pollfd info; - int timeoutMS; info.fd = fd; info.events = 0; @@ -52,7 +48,21 @@ int SDL_IOReady(int fd, int flags, Sint64 timeoutNS) if (flags & SDL_IOR_WRITE) { info.events |= POLLOUT; } - // FIXME: Add support for ppoll() for nanosecond precision + +#ifdef HAVE_PPOLL + struct timespec *timeout = NULL; + struct timespec ts; + + if (timeoutNS >= 0) { + ts.tv_sec = SDL_NS_TO_SECONDS(timeoutNS); + ts.tv_nsec = timeoutNS - SDL_SECONDS_TO_NS(ts.tv_sec); + timeout = &ts; + } + + result = ppoll(&info, 1, timeout, NULL); +#else + int timeoutMS; + if (timeoutNS > 0) { timeoutMS = (int)SDL_NS_TO_MS(timeoutNS + (SDL_NS_PER_MS - 1)); } else if (timeoutNS == 0) { @@ -61,34 +71,7 @@ int SDL_IOReady(int fd, int flags, Sint64 timeoutNS) timeoutMS = -1; } result = poll(&info, 1, timeoutMS); -#else - fd_set rfdset, *rfdp = NULL; - fd_set wfdset, *wfdp = NULL; - struct timeval tv, *tvp = NULL; - - // If this assert triggers we'll corrupt memory here - SDL_assert(fd >= 0 && fd < FD_SETSIZE); - - if (flags & SDL_IOR_READ) { - FD_ZERO(&rfdset); - FD_SET(fd, &rfdset); - rfdp = &rfdset; - } - if (flags & SDL_IOR_WRITE) { - FD_ZERO(&wfdset); - FD_SET(fd, &wfdset); - wfdp = &wfdset; - } - - if (timeoutNS >= 0) { - tv.tv_sec = (timeoutNS / SDL_NS_PER_SECOND); - tv.tv_usec = SDL_NS_TO_US((timeoutNS % SDL_NS_PER_SECOND) + (SDL_NS_PER_US - 1)); - tvp = &tv; - } - - result = select(fd + 1, rfdp, wfdp, NULL, tvp); -#endif // HAVE_POLL - +#endif } while (result < 0 && errno == EINTR && !(flags & SDL_IOR_NO_RETRY)); return result;