26 #elif defined(_MSC_VER)
39 #include <sys/epoll.h>
48 #if defined(TARGET_DARWIN)
49 #define SELECT_PREFERRED_OVER_POLL
66 #define SELECT_MAX_FDS FD_SETSIZE
68 #define SELECT_MAX_FDS 256
74 if (tv->tv_sec == 0 && tv->tv_usec == 0)
80 return max_int(tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000, 1);
99 ASSERT(i >= 0 && i < wes->capacity);
104 wes->
events[i] =
event->read;
109 wes->
events[i] =
event->write;
156 for (i = 0; i < len; ++i)
158 const HANDLE h = wes->
events[i];
159 if (h == event->
read || h == event->
write)
168 wes->
esr[j] = wes->
esr[i];
179 ASSERT(index >= 0 && index < wes->n_events);
180 for (i = index; i < wes->
n_events - 1; ++i)
183 wes->
esr[i] = wes->
esr[i+1];
195 const HANDLE h = wes->
events[i];
196 if (h == event->
read)
201 else if (h == event->
write)
377 msg(
M_FATAL,
"fatal error in we_ctl: rwflags=%d", rwflags);
383 msg(
D_EVENT_ERRORS,
"Error: Windows resource limit WSA_MAXIMUM_WAIT_EVENTS (%d) has been exceeded", WSA_MAXIMUM_WAIT_EVENTS);
413 status = WSAWaitForMultipleEvents(
434 if (WaitForSingleObject(wes->
events[i], 0) == WAIT_OBJECT_0)
458 status = WSAWaitForMultipleEvents(
466 if (outlen >= 1 &&
status >= WSA_WAIT_EVENT_0 &&
status < WSA_WAIT_EVENT_0 + (DWORD) wes->
n_events)
468 *out = wes->
esr[
status - WSA_WAIT_EVENT_0];
473 else if (
status == WSA_WAIT_TIMEOUT)
509 *maxevents =
min_int(*maxevents, WSA_MAXIMUM_WAIT_EVENTS);
533 struct epoll_event *events;
539 struct ep_set *eps = (
struct ep_set *) es;
548 const struct ep_set *eps = (
struct ep_set *) es;
555 struct epoll_event ev;
556 struct ep_set *eps = (
struct ep_set *) es;
562 if (epoll_ctl(eps->epfd, EPOLL_CTL_DEL, event, &ev) < 0)
564 msg(
M_WARN|
M_ERRNO,
"EVENT: epoll_ctl EPOLL_CTL_DEL failed, sd=%d", (
int)event);
569 ep_ctl(
struct event_set *es,
event_t event,
unsigned int rwflags,
void *arg)
571 struct ep_set *eps = (
struct ep_set *) es;
572 struct epoll_event ev;
579 ev.events |= EPOLLIN;
583 ev.events |= EPOLLOUT;
589 (
unsigned int)ev.events,
592 if (epoll_ctl(eps->epfd, EPOLL_CTL_MOD, event, &ev) < 0)
596 if (epoll_ctl(eps->epfd, EPOLL_CTL_ADD, event, &ev) < 0)
598 msg(
M_ERR,
"EVENT: epoll_ctl EPOLL_CTL_ADD failed, sd=%d", (
int)event);
603 msg(
M_ERR,
"EVENT: epoll_ctl EPOLL_CTL_MOD failed, sd=%d", (
int)event);
611 struct ep_set *eps = (
struct ep_set *) es;
614 if (outlen > eps->maxevents)
616 outlen = eps->maxevents;
625 const struct epoll_event *ev = eps->events;
627 for (i = 0; i < stat; ++i)
630 if (ev->events & (EPOLLIN|EPOLLPRI|EPOLLERR|EPOLLHUP))
634 if (ev->events & EPOLLOUT)
638 esr->
arg = ev->data.ptr;
649 ep_init(
int *maxevents,
unsigned int flags)
657 fd = epoll_create(*maxevents);
668 eps->func.free = ep_free;
669 eps->func.reset = ep_reset;
670 eps->func.del = ep_del;
671 eps->func.ctl = ep_ctl;
672 eps->func.wait = ep_wait;
682 eps->maxevents = *maxevents;
698 struct pollfd *events;
707 struct po_set *
pos = (
struct po_set *) es;
716 struct po_set *
pos = (
struct po_set *) es;
724 struct po_set *
pos = (
struct po_set *) es;
730 for (i = 0; i <
pos->n_events; ++i)
732 if (
pos->events[i].fd == event)
735 for (j = i; j <
pos->n_events - 1; ++j)
737 pos->events[j] =
pos->events[j+1];
738 pos->args[j] =
pos->args[j+1];
747 po_set_pollfd_events(
struct pollfd *pfdp,
unsigned int rwflags)
752 pfdp->events |= POLLOUT;
756 pfdp->events |= (POLLIN|POLLPRI);
761 po_append_event(
struct po_set *
pos,
event_t event,
unsigned int rwflags,
void *arg)
763 if (
pos->n_events <
pos->capacity)
765 struct pollfd *pfdp = &
pos->events[
pos->n_events];
767 pos->args[
pos->n_events] = arg;
768 po_set_pollfd_events(pfdp, rwflags);
779 po_ctl(
struct event_set *es,
event_t event,
unsigned int rwflags,
void *arg)
781 struct po_set *
pos = (
struct po_set *) es;
784 rwflags, (
int)event, (
ptr_type)arg);
788 if (!po_append_event(
pos, event, rwflags, arg))
796 for (i = 0; i <
pos->n_events; ++i)
798 struct pollfd *pfdp = &
pos->events[i];
799 if (pfdp->fd == event)
802 po_set_pollfd_events(pfdp, rwflags);
806 if (!po_append_event(
pos, event, rwflags, arg))
822 struct po_set *
pos = (
struct po_set *) es;
827 ASSERT(stat <= pos->n_events);
832 const struct pollfd *pfdp =
pos->events;
833 for (i = 0; i <
pos->n_events && j < outlen; ++i)
835 if (pfdp->revents & (POLLIN|POLLPRI|POLLERR|POLLHUP|POLLOUT))
838 if (pfdp->revents & (POLLIN|POLLPRI|POLLERR|POLLHUP))
842 if (pfdp->revents & POLLOUT)
852 else if (pfdp->revents)
855 (
unsigned int)pfdp->revents, pfdp->fd);
865 po_init(
int *maxevents,
unsigned int flags)
874 pos->func.free = po_free;
875 pos->func.reset = po_reset;
876 pos->func.del = po_del;
877 pos->func.ctl = po_ctl;
878 pos->func.wait = po_wait;
889 pos->capacity = *maxevents;
917 struct se_set *ses = (
struct se_set *) es;
925 struct se_set *ses = (
struct se_set *) es;
931 FD_ZERO(&ses->readfds);
932 FD_ZERO(&ses->writefds);
933 for (i = 0; i <= ses->maxfd; ++i)
943 struct se_set *ses = (
struct se_set *) es;
948 if (event >= 0 && event < ses->capacity)
950 FD_CLR(event, &ses->readfds);
951 FD_CLR(event, &ses->writefds);
952 ses->args[event] = NULL;
962 se_ctl(
struct event_set *es,
event_t event,
unsigned int rwflags,
void *arg)
964 struct se_set *ses = (
struct se_set *) es;
967 rwflags, (
int)event, (
int)ses->fast, ses->capacity, ses->maxfd, (
ptr_type)arg);
969 if (event >= 0 && event < ses->capacity)
971 ses->maxfd =
max_int(event, ses->maxfd);
972 ses->args[event] = arg;
992 FD_CLR(event, &ses->readfds);
1000 FD_CLR(event, &ses->writefds);
1013 se_wait_return(
struct se_set *ses,
1020 for (i = 0; i <= ses->maxfd && j < outlen; ++i)
1022 const bool r = FD_ISSET(i,
read);
1023 const bool w = FD_ISSET(i,
write);
1035 out->
arg = ses->args[i];
1048 struct se_set *ses = (
struct se_set *) es;
1049 struct timeval tv_tmp = *tv;
1054 (int64_t)tv_tmp.tv_sec,
1055 (
long)tv_tmp.tv_usec);
1057 stat = select(ses->maxfd + 1, &ses->readfds, &ses->writefds, NULL, &tv_tmp);
1061 stat = se_wait_return(ses, &ses->readfds, &ses->writefds, out, outlen);
1070 struct se_set *ses = (
struct se_set *) es;
1071 struct timeval tv_tmp = *tv;
1072 fd_set
read = ses->readfds;
1073 fd_set
write = ses->writefds;
1077 ses->maxfd, (int64_t)tv_tmp.tv_sec, (
long)tv_tmp.tv_usec);
1079 stat = select(ses->maxfd + 1, &
read, &
write, NULL, &tv_tmp);
1083 stat = se_wait_return(ses, &
read, &
write, out, outlen);
1090 se_init(
int *maxevents,
unsigned int flags)
1094 dmsg(
D_EVENT_WAIT,
"SE_INIT maxevents=%d flags=0x%08x", *maxevents, flags);
1099 ses->func.free = se_free;
1100 ses->func.reset = se_reset;
1101 ses->func.del = se_del;
1102 ses->func.ctl = se_ctl;
1103 ses->func.wait = se_wait_scalable;
1108 ses->func.wait = se_wait_fast;
1131 ret =
we_init(maxevents, flags);
1132 #elif POLL && SELECT
1136 ret = se_init(maxevents, flags);
1139 #ifdef SELECT_PREFERRED_OVER_POLL
1142 ret = se_init(maxevents, flags);
1146 ret = po_init(maxevents, flags);
1151 ret = po_init(maxevents, flags);
1155 ret = se_init(maxevents, flags);
1159 ret = po_init(maxevents, flags);
1161 ret = se_init(maxevents, flags);
1163 #error At least one of poll, select, or WSAWaitForMultipleEvents must be supported by the kernel
1174 ret = ep_init(maxevents, flags);
1177 msg(
M_WARN,
"Note: sys_epoll API is unavailable, falling back to poll/select API");