Browse Source

Use kqueue as alternative to epoll for CLAP posix fd on BSDs

pull/1689/head
falkTX 2 years ago
parent
commit
d9f3d78ab8
1 changed files with 42 additions and 11 deletions
  1. +42
    -11
      source/backend/plugin/CarlaPluginCLAP.cpp

+ 42
- 11
source/backend/plugin/CarlaPluginCLAP.cpp View File

@@ -33,8 +33,14 @@
#include "water/misc/Time.h" #include "water/misc/Time.h"


#ifdef _POSIX_VERSION #ifdef _POSIX_VERSION
# include <sys/epoll.h>
# include <sys/socket.h>
# if defined(CARLA_OS_MAC) || defined(CARLA_OS_BSD)
# define CARLA_CLAP_POSIX_KQUEUE
# include <sys/event.h>
# include <sys/types.h>
# else
# define CARLA_CLAP_POSIX_EPOLL
# include <sys/epoll.h>
# endif
#endif #endif


// FIXME // FIXME
@@ -2665,24 +2671,29 @@ protected:


if (flags & (CLAP_POSIX_FD_READ|CLAP_POSIX_FD_WRITE)) if (flags & (CLAP_POSIX_FD_READ|CLAP_POSIX_FD_WRITE))
{ {
const int epollfd = ::epoll_create1(0);
CARLA_SAFE_ASSERT_RETURN(epollfd >= 0, false);
#ifdef CARLA_CLAP_POSIX_KQUEUE
const int hostFd = ::kqueue();
#else
CARLA_SAFE_ASSERT_RETURN(hostFd >= 0, false);
#endif


epoll_event ev = {};
#ifndef CARLA_CLAP_POSIX_KQUEUE
struct epoll_event ev = {};
if (flags & CLAP_POSIX_FD_READ) if (flags & CLAP_POSIX_FD_READ)
ev.events |= EPOLLIN; ev.events |= EPOLLIN;
if (flags & CLAP_POSIX_FD_WRITE) if (flags & CLAP_POSIX_FD_WRITE)
ev.events |= EPOLLOUT; ev.events |= EPOLLOUT;
ev.data.fd = fd; ev.data.fd = fd;


if (::epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) < 0)
if (::epoll_ctl(hostFd, EPOLL_CTL_ADD, fd, &ev) < 0)
{ {
::close(epollfd);
::close(hostFd);
return false; return false;
} }
#endif


const HostPosixFileDescriptorDetails posixFD = { const HostPosixFileDescriptorDetails posixFD = {
epollfd,
hostFd,
fd, fd,
flags, flags,
}; };
@@ -2706,7 +2717,8 @@ protected:
if (posixFD.flags == flags) if (posixFD.flags == flags)
return true; return true;


epoll_event ev = {};
#ifndef CARLA_CLAP_POSIX_KQUEUE
struct epoll_event ev = {};
if (flags & CLAP_POSIX_FD_READ) if (flags & CLAP_POSIX_FD_READ)
ev.events |= EPOLLIN; ev.events |= EPOLLIN;
if (flags & CLAP_POSIX_FD_WRITE) if (flags & CLAP_POSIX_FD_WRITE)
@@ -2715,6 +2727,7 @@ protected:


if (::epoll_ctl(posixFD.hostFd, EPOLL_CTL_MOD, fd, &ev) < 0) if (::epoll_ctl(posixFD.hostFd, EPOLL_CTL_MOD, fd, &ev) < 0)
return false; return false;
#endif


posixFD.flags = flags; posixFD.flags = flags;
return true; return true;
@@ -2733,7 +2746,9 @@ protected:


if (posixFD.pluginFd == fd) if (posixFD.pluginFd == fd)
{ {
#ifndef CARLA_CLAP_POSIX_KQUEUE
::epoll_ctl(posixFD.hostFd, EPOLL_CTL_DEL, fd, nullptr); ::epoll_ctl(posixFD.hostFd, EPOLL_CTL_DEL, fd, nullptr);
#endif
::close(posixFD.hostFd); ::close(posixFD.hostFd);
fPosixFileDescriptors.remove(it); fPosixFileDescriptors.remove(it);
return true; return true;
@@ -3116,10 +3131,22 @@ private:
{ {
const HostPosixFileDescriptorDetails& posixFD(it.getValue(kPosixFileDescriptorFallback)); const HostPosixFileDescriptorDetails& posixFD(it.getValue(kPosixFileDescriptorFallback));


epoll_event events;
#ifdef CARLA_CLAP_POSIX_KQUEUE
const int16_t filter = posixFD.flags & CLAP_POSIX_FD_WRITE ? EVFILT_WRITE : EVFILT_READ;
struct kevent kev = {}, event;
struct timespec timeout = {};
EV_SET(&kev, posixFD.pluginFd, filter, EV_ADD|EV_ENABLE, 0, 0, nullptr);
#else
epoll_event event;
#endif

for (int i=0; i<50; ++i) for (int i=0; i<50; ++i)
{ {
switch (::epoll_wait(posixFD.hostFd, &events, 1, 0))
#ifdef CARLA_CLAP_POSIX_KQUEUE
switch (kevent(posixFD.hostFd, &kev, 1, &event, 1, &timeout))
#else
switch (::epoll_wait(posixFD.hostFd, &event, 1, 0))
#endif
{ {
case 1: case 1:
fExtensions.posixFD->on_fd(fPlugin, posixFD.pluginFd, posixFD.flags); fExtensions.posixFD->on_fd(fPlugin, posixFD.pluginFd, posixFD.flags);
@@ -3130,6 +3157,10 @@ private:
case 0: case 0:
i = 50; i = 50;
break; break;
default:
carla_safe_exception("posix fd received abnormal value", __FILE__, __LINE__);
i = 50;
break;
} }
} }
} }


Loading…
Cancel
Save