mirror of
https://github.com/libretro/RetroArch.git
synced 2026-11-07 08:36:02 -10:00
udev: finish the kqueue code path so the BSDs no longer need libepoll-shim
udev_input.c had a half-written kqueue alternative to epoll behind a "#if 1 / TODO" that hard-selected epoll everywhere, which is why the FreeBSD games/retroarch port has to link the udev input driver against libepoll-shim (UDEV_LIB_DEPENDS/UDEV_CFLAGS/UDEV_LDFLAGS in the port). Complete it: on FreeBSD, OpenBSD, NetBSD, DragonFly and macOS the evdev fds are registered with EV_SET(EVFILT_READ, EV_ADD, udata = device) (the placeholder referenced an undefined LISTENSOCKET), the poll uses a zero timespec like the epoll_wait(..., 0) it mirrors (the placeholder referenced an undefined `timeout`), and the event loop tests filter == EVFILT_READ && !(flags & EV_ERROR) instead of the epoll-only `events & EPOLLIN`. kqueue is level-triggered by default so the drain-until-EAGAIN read loop is unchanged, and closing a device fd removes it from the kqueue just as it does from the epoll set. NetBSD's kevent.udata is intptr_t rather than void *, hence the UDEV_KQ_UDATA cast. Linux still uses epoll; that object is unchanged. The kqueue variant was compiled with libkqueue's <sys/event.h> to catch type errors. CI: the FreeBSD job now fails if the linked retroarch binary still imports any epoll_* symbol.
This commit is contained in:
1 parent
422ed61c9d
commit
4e1eb70caa
2 files changed
+25
-14
No files matched your search
@@ -71,6 +71,11 @@ jobs:
|
||||
gmake -j$NCPU clean
|
||||
gmake -j$NCPU info all
|
||||
./retroarch --version
|
||||
# udev input must multiplex with kqueue here, so the binary
|
||||
# must not need libepoll-shim's epoll_* at all.
|
||||
if nm -u retroarch | grep -q 'epoll_'; then
|
||||
echo "retroarch still references epoll (libepoll-shim)"; exit 1
|
||||
fi
|
||||
|
||||
# With v4l_compat the V4L2 camera and video processor core
|
||||
# must still compile; only those two objects are rebuilt.
|
||||
|
||||
+20
-14
@@ -14,18 +14,12 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* TODO/FIXME - set this once the kqueue codepath is implemented and working properly,
|
||||
* also remove libepoll-shim from the Makefile when that happens. */
|
||||
#if 1
|
||||
#define HAVE_EPOLL
|
||||
#else
|
||||
#ifdef __linux__
|
||||
#define HAVE_EPOLL 1
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
|
||||
/* Linux multiplexes the evdev fds with epoll; the BSDs and macOS use
|
||||
* kqueue natively so no libepoll-shim is needed there. */
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
#define HAVE_KQUEUE 1
|
||||
#endif
|
||||
#else
|
||||
#define HAVE_EPOLL 1
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -43,6 +37,13 @@
|
||||
#include <sys/epoll.h>
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
#include <sys/event.h>
|
||||
#include <sys/time.h>
|
||||
/* NetBSD declares kevent.udata as intptr_t, everyone else as void *. */
|
||||
#if defined(__NetBSD__)
|
||||
#define UDEV_KQ_UDATA(ptr) ((intptr_t)(ptr))
|
||||
#else
|
||||
#define UDEV_KQ_UDATA(ptr) ((void*)(ptr))
|
||||
#endif
|
||||
#endif
|
||||
#include <poll.h>
|
||||
|
||||
@@ -3295,7 +3296,7 @@ static int udev_input_add_device(udev_input_t *udev,
|
||||
fd, strerror(errno));
|
||||
}
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, LISTENSOCKET);
|
||||
EV_SET(&event, fd, EVFILT_READ, EV_ADD, 0, 0, UDEV_KQ_UDATA(device));
|
||||
if (kevent(udev->fd, &event, 1, NULL, 0, NULL) == -1)
|
||||
{
|
||||
RARCH_ERR("[udev] Failed to add FD (%d) to kqueue list (%s).\n",
|
||||
@@ -3540,8 +3541,9 @@ static void udev_input_poll(void *data)
|
||||
ret = epoll_wait(udev->fd, events, ARRAY_SIZE(events), 0);
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
{
|
||||
/* Zero timeout: drain what is pending, never block the frame. */
|
||||
struct timespec timeoutspec;
|
||||
timeoutspec.tv_sec = timeout;
|
||||
timeoutspec.tv_sec = 0;
|
||||
timeoutspec.tv_nsec = 0;
|
||||
ret = kevent(udev->fd, NULL, 0, events,
|
||||
ARRAY_SIZE(events), &timeoutspec);
|
||||
@@ -3550,8 +3552,12 @@ static void udev_input_poll(void *data)
|
||||
|
||||
for (i = 0; i < ret; i++)
|
||||
{
|
||||
/* TODO/FIXME - add HAVE_EPOLL/HAVE_KQUEUE codepaths here */
|
||||
#if defined(HAVE_EPOLL)
|
||||
if (events[i].events & EPOLLIN)
|
||||
#elif defined(HAVE_KQUEUE)
|
||||
if ( events[i].filter == EVFILT_READ
|
||||
&& !(events[i].flags & EV_ERROR))
|
||||
#endif
|
||||
{
|
||||
int j, len;
|
||||
struct input_event input_events[32];
|
||||
|
||||
Reference in new issue
Block a user