37 #include <sys/epoll.h>
46 #if defined(TARGET_DARWIN)
47 #define SELECT_PREFERRED_OVER_POLL
64 #define SELECT_MAX_FDS FD_SETSIZE
66 #define SELECT_MAX_FDS 256
72 if (tv->tv_sec == 0 && tv->tv_usec == 0)
78 return max_int(tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000, 1);
97 ASSERT(i >= 0 && i < wes->capacity);
102 wes->
events[i] =
event->read;
107 wes->
events[i] =
event->write;
154 for (i = 0; i < len; ++i)
156 const HANDLE h = wes->
events[i];
157 if (h == event->
read || h == event->
write)
166 wes->
esr[j] = wes->
esr[i];
177 ASSERT(index >= 0 && index < wes->n_events);
178 for (i = index; i < wes->
n_events - 1; ++i)
181 wes->
esr[i] = wes->
esr[i+1];
193 const HANDLE h = wes->
events[i];
194 if (h == event->
read)
199 else if (h == event->
write)
375 msg(
M_FATAL,
"fatal error in we_ctl: rwflags=%d", rwflags);
381 msg(
D_EVENT_ERRORS,
"Error: Windows resource limit WSA_MAXIMUM_WAIT_EVENTS (%d) has been exceeded", WSA_MAXIMUM_WAIT_EVENTS);
411 status = WSAWaitForMultipleEvents(
432 if (WaitForSingleObject(wes->
events[i], 0) == WAIT_OBJECT_0)
456 status = WSAWaitForMultipleEvents(
464 if (outlen >= 1 &&
status >= WSA_WAIT_EVENT_0 &&
status < WSA_WAIT_EVENT_0 + (DWORD) wes->
n_events)
466 *out = wes->
esr[
status - WSA_WAIT_EVENT_0];
471 else if (
status == WSA_WAIT_TIMEOUT)
507 *maxevents =
min_int(*maxevents, WSA_MAXIMUM_WAIT_EVENTS);
531 struct epoll_event *events;
537 struct ep_set *eps = (
struct ep_set *)
es;
546 const struct ep_set *eps = (
struct ep_set *)
es;
553 struct epoll_event ev;
554 struct ep_set *eps = (
struct ep_set *)
es;
560 if (epoll_ctl(eps->epfd, EPOLL_CTL_DEL, event, &ev) < 0)
562 msg(
M_WARN|
M_ERRNO,
"EVENT: epoll_ctl EPOLL_CTL_DEL failed, sd=%d", (
int)event);
569 struct ep_set *eps = (
struct ep_set *)
es;
570 struct epoll_event ev;
577 ev.events |= EPOLLIN;
581 ev.events |= EPOLLOUT;
587 (
unsigned int)ev.events,
590 if (epoll_ctl(eps->epfd, EPOLL_CTL_MOD, event, &ev) < 0)
594 if (epoll_ctl(eps->epfd, EPOLL_CTL_ADD, event, &ev) < 0)
596 msg(
M_ERR,
"EVENT: epoll_ctl EPOLL_CTL_ADD failed, sd=%d", (
int)event);
601 msg(
M_ERR,
"EVENT: epoll_ctl EPOLL_CTL_MOD failed, sd=%d", (
int)event);
609 struct ep_set *eps = (
struct ep_set *)
es;
612 if (outlen > eps->maxevents)
614 outlen = eps->maxevents;
623 const struct epoll_event *ev = eps->events;
625 for (i = 0; i < stat; ++i)
628 if (ev->events & (EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP))
632 if (ev->events & EPOLLOUT)
636 esr->
arg = ev->data.ptr;
647 ep_init(
int *maxevents,
unsigned int flags)
655 fd = epoll_create(*maxevents);
666 eps->func.free = ep_free;
667 eps->func.reset = ep_reset;
668 eps->func.del = ep_del;
669 eps->func.ctl = ep_ctl;
670 eps->func.wait = ep_wait;
680 eps->maxevents = *maxevents;
696 struct pollfd *events;
705 struct po_set *
pos = (
struct po_set *)
es;
714 struct po_set *
pos = (
struct po_set *)
es;
722 struct po_set *
pos = (
struct po_set *)
es;
728 for (i = 0; i <
pos->n_events; ++i)
730 if (
pos->events[i].fd == event)
733 for (j = i; j <
pos->n_events - 1; ++j)
735 pos->events[j] =
pos->events[j+1];
736 pos->args[j] =
pos->args[j+1];
745 po_set_pollfd_events(
struct pollfd *pfdp,
unsigned int rwflags)
750 pfdp->events |= POLLOUT;
754 pfdp->events |= (POLLIN|POLLPRI);
759 po_append_event(
struct po_set *
pos,
event_t event,
unsigned int rwflags,
void *arg)
761 if (
pos->n_events <
pos->capacity)
763 struct pollfd *pfdp = &
pos->events[
pos->n_events];
765 pos->args[
pos->n_events] = arg;
766 po_set_pollfd_events(pfdp, rwflags);
779 struct po_set *
pos = (
struct po_set *)
es;
782 rwflags, (
int)event, (
ptr_type)arg);
786 if (!po_append_event(
pos, event, rwflags, arg))
794 for (i = 0; i <
pos->n_events; ++i)
796 struct pollfd *pfdp = &
pos->events[i];
797 if (pfdp->fd == event)
800 po_set_pollfd_events(pfdp, rwflags);
804 if (!po_append_event(
pos, event, rwflags, arg))
820 struct po_set *
pos = (
struct po_set *)
es;
825 ASSERT(stat <= pos->n_events);
830 const struct pollfd *pfdp =
pos->events;
831 for (i = 0; i <
pos->n_events && j < outlen; ++i)
833 if (pfdp->revents & (POLLIN|POLLPRI|POLLERR|POLLHUP|POLLOUT))
836 if (pfdp->revents & (POLLIN|POLLPRI|POLLERR|POLLHUP))
840 if (pfdp->revents & POLLOUT)
850 else if (pfdp->revents)
853 (
unsigned int)pfdp->revents, pfdp->fd);
863 po_init(
int *maxevents,
unsigned int flags)
872 pos->func.free = po_free;
873 pos->func.reset = po_reset;
874 pos->func.del = po_del;
875 pos->func.ctl = po_ctl;
876 pos->func.wait = po_wait;
887 pos->capacity = *maxevents;
915 struct se_set *ses = (
struct se_set *)
es;
923 struct se_set *ses = (
struct se_set *)
es;
929 FD_ZERO(&ses->readfds);
930 FD_ZERO(&ses->writefds);
931 for (i = 0; i <= ses->maxfd; ++i)
941 struct se_set *ses = (
struct se_set *)
es;
946 if (event >= 0 && event < ses->capacity)
948 FD_CLR(event, &ses->readfds);
949 FD_CLR(event, &ses->writefds);
950 ses->args[event] = NULL;
962 struct se_set *ses = (
struct se_set *)
es;
965 rwflags, (
int)event, (
int)ses->fast, ses->capacity, ses->maxfd, (
ptr_type)arg);
967 if (event >= 0 && event < ses->capacity)
969 ses->maxfd =
max_int(event, ses->maxfd);
970 ses->args[event] = arg;
990 FD_CLR(event, &ses->readfds);
998 FD_CLR(event, &ses->writefds);
1011 se_wait_return(
struct se_set *ses,
1018 for (i = 0; i <= ses->maxfd && j < outlen; ++i)
1020 const bool r = FD_ISSET(i,
read);
1021 const bool w = FD_ISSET(i,
write);
1033 out->
arg = ses->args[i];
1046 struct se_set *ses = (
struct se_set *)
es;
1047 struct timeval tv_tmp = *tv;
1052 (int64_t)tv_tmp.tv_sec,
1053 (
long)tv_tmp.tv_usec);
1055 stat = select(ses->maxfd + 1, &ses->readfds, &ses->writefds, NULL, &tv_tmp);
1059 stat = se_wait_return(ses, &ses->readfds, &ses->writefds, out, outlen);
1068 struct se_set *ses = (
struct se_set *)
es;
1069 struct timeval tv_tmp = *tv;
1070 fd_set
read = ses->readfds;
1071 fd_set
write = ses->writefds;
1075 ses->maxfd, (int64_t)tv_tmp.tv_sec, (
long)tv_tmp.tv_usec);
1077 stat = select(ses->maxfd + 1, &
read, &
write, NULL, &tv_tmp);
1081 stat = se_wait_return(ses, &
read, &
write, out, outlen);
1088 se_init(
int *maxevents,
unsigned int flags)
1092 dmsg(
D_EVENT_WAIT,
"SE_INIT maxevents=%d flags=0x%08x", *maxevents, flags);
1097 ses->func.free = se_free;
1098 ses->func.reset = se_reset;
1099 ses->func.del = se_del;
1100 ses->func.ctl = se_ctl;
1101 ses->func.wait = se_wait_scalable;
1106 ses->func.wait = se_wait_fast;
1129 ret =
we_init(maxevents, flags);
1130 #elif POLL && SELECT
1134 ret = se_init(maxevents, flags);
1137 #ifdef SELECT_PREFERRED_OVER_POLL
1140 ret = se_init(maxevents, flags);
1144 ret = po_init(maxevents, flags);
1149 ret = po_init(maxevents, flags);
1153 ret = se_init(maxevents, flags);
1157 ret = po_init(maxevents, flags);
1159 ret = se_init(maxevents, flags);
1161 #error At least one of poll, select, or WSAWaitForMultipleEvents must be supported by the kernel
1172 ret = ep_init(maxevents, flags);
1175 msg(
M_WARN,
"Note: sys_epoll API is unavailable, falling back to poll/select API");