Linux: Use the more efficient eventfd mechanism to wakeup the event loop

This commit is contained in:
Kovid Goyal 2019-07-05 09:51:52 +05:30
parent 0fb1481038
commit 6d96a89328
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 28 additions and 2 deletions

21
glfw/backend_utils.c vendored
View File

@ -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

View File

@ -29,6 +29,11 @@
#include <unistd.h>
#include <stdbool.h>
#if __has_include(<sys/eventfd.h>)
#define HAS_EVENT_FD
#include <sys/eventfd.h>
#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];