mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-10-26 12:27:44 +00:00
unix: Add ppoll support
Allows for finer grained timeout values, and fixes a FIXME. This also drops the legacy select() fallback path in favor of presuming that poll() is always available. poll() is part of the POSIX.1-2001 standard, has been available in Unix since some time in the 1980s, the BSDs since at least the early 90s, and Linux since kernel 2.1, which predates kernel support for Pthreads. glibc also has its own emulation using select(), if necessary.
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -23,15 +23,13 @@
|
||||
|
||||
#include "SDL_poll.h"
|
||||
|
||||
#ifdef HAVE_POLL
|
||||
#include <poll.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_PPOLL
|
||||
#include <time.h>
|
||||
#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;
|
||||
|
||||
Reference in New Issue
Block a user