diff --git a/glfw/backend_utils.c b/glfw/backend_utils.c index f681cb469..1dafa8c5f 100644 --- a/glfw/backend_utils.c +++ b/glfw/backend_utils.c @@ -229,18 +229,30 @@ drain_wakeup_fd(int fd, int events UNUSED, void* data UNUSED) { bool initPollData(EventLoopData *eld, int display_fd) { - if (pipe2(eld->wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0) return false; addWatch(eld, "display", display_fd, POLLIN, 1, NULL, NULL); +#ifdef HAS_EVENT_FD + eld->wakeupFd = eventfd(0, 0); + if (eld->wakeupFd == -1) return false; + addWatch(eld, "wakeup", eld->wakeupFd, POLLIN, 1, drain_wakeup_fd, NULL); +#else + if (pipe2(eld->wakeupFds, O_CLOEXEC | O_NONBLOCK) != 0) return false; addWatch(eld, "wakeup", eld->wakeupFds[0], POLLIN, 1, drain_wakeup_fd, NULL); +#endif return true; } void wakeupEventLoop(EventLoopData *eld) { +#ifdef HAS_EVENT_FD + static const int64_t value = 1; + while (write(eld->wakeupFd, &value, sizeof value) < 0 && errno == EINTR); +#else while (write(eld->wakeupFds[1], "w", 1) < 0 && errno == EINTR); +#endif } -static void +#ifndef HAS_EVENT_FD +static inline void closeFds(int *fds, size_t count) { while(count--) { if (*fds > 0) { @@ -250,10 +262,15 @@ closeFds(int *fds, size_t count) { fds++; } } +#endif void finalizePollData(EventLoopData *eld) { +#ifdef HAS_EVENT_FD + close(eld->wakeupFd); eld->wakeupFd = -1; +#else closeFds(eld->wakeupFds, arraysz(eld->wakeupFds)); +#endif } int diff --git a/glfw/backend_utils.h b/glfw/backend_utils.h index 66e0434bd..414be39fe 100644 --- a/glfw/backend_utils.h +++ b/glfw/backend_utils.h @@ -29,6 +29,11 @@ #include #include +#if __has_include() +#define HAS_EVENT_FD +#include +#endif + typedef unsigned long long id_type; typedef void(*watch_callback_func)(int, int, void*); typedef void(*timer_callback_func)(id_type, void*); @@ -56,7 +61,11 @@ typedef struct { typedef struct { struct pollfd fds[32]; +#ifdef HAS_EVENT_FD + int wakeupFd; +#else int wakeupFds[2]; +#endif nfds_t watches_count, timers_count; Watch watches[32]; Timer timers[128];