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