45#if defined(TARGET_DARWIN)
46#define SELECT_PREFERRED_OVER_POLL
63#define SELECT_MAX_FDS FD_SETSIZE
65#define SELECT_MAX_FDS 256
71 if (tv->tv_sec == 0 && tv->tv_usec == 0)
77 return max_int(tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000, 1);
96 ASSERT(
i >= 0 && i < wes->capacity);
153 for (
i = 0;
i < len; ++
i)
155 const HANDLE h = wes->
events[
i];
156 if (h == event->
read || h == event->
write)
176 ASSERT(index >= 0 && index < wes->n_events);
192 const HANDLE h = wes->
events[
i];
193 if (h == event->
read)
198 else if (h == event->
write)
371 msg(
M_FATAL,
"fatal error in we_ctl: rwflags=%d", rwflags);
378 "Error: Windows resource limit WSA_MAXIMUM_WAIT_EVENTS (%d) has been exceeded",
379 WSA_MAXIMUM_WAIT_EVENTS);
422 if (WaitForSingleObject(wes->
events[
i], 0) == WAIT_OBJECT_0)
447 (DWORD)timeout, FALSE);
450 if (outlen >= 1 &&
status >= WSA_WAIT_EVENT_0
453 *out = wes->
esr[
status - WSA_WAIT_EVENT_0];
458 else if (
status == WSA_WAIT_TIMEOUT)
494 *maxevents =
min_int(*maxevents, WSA_MAXIMUM_WAIT_EVENTS);
517 struct epoll_event *events;
523 struct ep_set *eps = (
struct ep_set *)
es;
532 const struct ep_set *eps = (
struct ep_set *)
es;
539 struct epoll_event ev;
540 struct ep_set *eps = (
struct ep_set *)
es;
546 if (epoll_ctl(eps->epfd, EPOLL_CTL_DEL, event, &ev) < 0)
548 msg(
M_WARN |
M_ERRNO,
"EVENT: epoll_ctl EPOLL_CTL_DEL failed, sd=%d", (
int)event);
555 struct ep_set *eps = (
struct ep_set *)
es;
556 struct epoll_event ev;
563 ev.events |= EPOLLIN;
567 ev.events |= EPOLLOUT;
571 (
unsigned int)ev.events, (
ptr_type)ev.data.ptr);
573 if (epoll_ctl(eps->epfd, EPOLL_CTL_MOD, event, &ev) < 0)
577 if (epoll_ctl(eps->epfd, EPOLL_CTL_ADD, event, &ev) < 0)
579 msg(
M_ERR,
"EVENT: epoll_ctl EPOLL_CTL_ADD failed, sd=%d", (
int)event);
584 msg(
M_ERR,
"EVENT: epoll_ctl EPOLL_CTL_MOD failed, sd=%d", (
int)event);
592 struct ep_set *eps = (
struct ep_set *)
es;
595 if (outlen > eps->maxevents)
597 outlen = eps->maxevents;
606 const struct epoll_event *ev = eps->events;
608 for (
i = 0;
i < stat; ++
i)
611 if (ev->events & (EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP))
615 if (ev->events & EPOLLOUT)
619 esr->
arg = ev->data.ptr;
630ep_init(
int *maxevents,
unsigned int flags)
638 fd = epoll_create(*maxevents);
649 eps->func.free = ep_free;
650 eps->func.reset = ep_reset;
651 eps->func.del = ep_del;
652 eps->func.ctl = ep_ctl;
653 eps->func.wait = ep_wait;
663 eps->maxevents = *maxevents;
679 struct pollfd *events;
688 struct po_set *
pos = (
struct po_set *)
es;
697 struct po_set *
pos = (
struct po_set *)
es;
705 struct po_set *
pos = (
struct po_set *)
es;
711 for (
i = 0;
i <
pos->n_events; ++
i)
713 if (
pos->events[
i].fd == event)
716 for (j =
i; j <
pos->n_events - 1; ++j)
718 pos->events[j] =
pos->events[j + 1];
719 pos->args[j] =
pos->args[j + 1];
728po_set_pollfd_events(
struct pollfd *pfdp,
unsigned int rwflags)
733 pfdp->events |= POLLOUT;
737 pfdp->events |= (POLLIN | POLLPRI);
742po_append_event(
struct po_set *
pos,
event_t event,
unsigned int rwflags,
void *arg)
744 if (
pos->n_events <
pos->capacity)
746 struct pollfd *pfdp = &
pos->events[
pos->n_events];
748 pos->args[
pos->n_events] = arg;
749 po_set_pollfd_events(pfdp, rwflags);
762 struct po_set *
pos = (
struct po_set *)
es;
769 if (!po_append_event(
pos, event, rwflags, arg))
777 for (
i = 0;
i <
pos->n_events; ++
i)
779 struct pollfd *pfdp = &
pos->events[
i];
780 if (pfdp->fd == event)
783 po_set_pollfd_events(pfdp, rwflags);
787 if (!po_append_event(
pos, event, rwflags, arg))
803 struct po_set *
pos = (
struct po_set *)
es;
808 ASSERT(stat <= pos->n_events);
813 const struct pollfd *pfdp =
pos->events;
814 for (
i = 0;
i <
pos->n_events && j < outlen; ++
i)
816 if (pfdp->revents & (POLLIN | POLLPRI | POLLERR | POLLHUP | POLLOUT))
819 if (pfdp->revents & (POLLIN | POLLPRI | POLLERR | POLLHUP))
823 if (pfdp->revents & POLLOUT)
829 "PO_WAIT[%d,%d] fd=%d rev=0x%08x rwflags=0x%04x arg=" ptr_format " %s",
i, j,
831 pos->fast ?
"" :
"[scalable]");
835 else if (pfdp->revents)
838 (
unsigned int)pfdp->revents, pfdp->fd);
848po_init(
int *maxevents,
unsigned int flags)
857 pos->func.free = po_free;
858 pos->func.reset = po_reset;
859 pos->func.del = po_del;
860 pos->func.ctl = po_ctl;
861 pos->func.wait = po_wait;
872 pos->capacity = *maxevents;
900 struct se_set *ses = (
struct se_set *)
es;
908 struct se_set *ses = (
struct se_set *)
es;
914 FD_ZERO(&ses->readfds);
915 FD_ZERO(&ses->writefds);
916 for (
i = 0;
i <= ses->maxfd; ++
i)
926 struct se_set *ses = (
struct se_set *)
es;
931 if (event >= 0 && event < ses->capacity)
933 FD_CLR(event, &ses->readfds);
934 FD_CLR(event, &ses->writefds);
935 ses->args[event] = NULL;
947 struct se_set *ses = (
struct se_set *)
es;
950 rwflags, (
int)event, (
int)ses->fast, ses->capacity, ses->maxfd, (
ptr_type)arg);
952 if (event >= 0 && event < ses->capacity)
954 ses->maxfd =
max_int(event, ses->maxfd);
955 ses->args[event] = arg;
975 FD_CLR(event, &ses->readfds);
983 FD_CLR(event, &ses->writefds);
989 msg(
D_EVENT_ERRORS,
"Error: select: too many I/O wait events, fd=%d cap=%d", (
int)event,
999 for (
i = 0;
i <= ses->maxfd && j < outlen; ++
i)
1001 const bool r = FD_ISSET(
i,
read);
1002 const bool w = FD_ISSET(
i,
write);
1014 out->
arg = ses->args[
i];
1028 struct se_set *ses = (
struct se_set *)
es;
1029 struct timeval tv_tmp = *tv;
1033 (int64_t)tv_tmp.tv_sec, (
long)tv_tmp.tv_usec);
1035 stat = select(ses->maxfd + 1, &ses->readfds, &ses->writefds, NULL, &tv_tmp);
1039 stat = se_wait_return(ses, &ses->readfds, &ses->writefds, out, outlen);
1049 struct se_set *ses = (
struct se_set *)
es;
1050 struct timeval tv_tmp = *tv;
1051 fd_set
read = ses->readfds;
1052 fd_set
write = ses->writefds;
1055 dmsg(
D_EVENT_WAIT,
"SE_WAIT_SCALEABLE maxfd=%d tv=%" PRIi64
"/%ld", ses->maxfd,
1056 (int64_t)tv_tmp.tv_sec, (
long)tv_tmp.tv_usec);
1058 stat = select(ses->maxfd + 1, &
read, &
write, NULL, &tv_tmp);
1062 stat = se_wait_return(ses, &
read, &
write, out, outlen);
1069se_init(
int *maxevents,
unsigned int flags)
1073 dmsg(
D_EVENT_WAIT,
"SE_INIT maxevents=%d flags=0x%08x", *maxevents, flags);
1078 ses->func.free = se_free;
1079 ses->func.reset = se_reset;
1080 ses->func.del = se_del;
1081 ses->func.ctl = se_ctl;
1082 ses->func.wait = se_wait_scalable;
1087 ses->func.wait = se_wait_fast;
1110 ret =
we_init(maxevents, flags);
1115 ret = se_init(maxevents, flags);
1118#ifdef SELECT_PREFERRED_OVER_POLL
1121 ret = se_init(maxevents, flags);
1125 ret = po_init(maxevents, flags);
1130 ret = po_init(maxevents, flags);
1134 ret = se_init(maxevents, flags);
1138 ret = po_init(maxevents, flags);
1140 ret = se_init(maxevents, flags);
1142#error At least one of poll, select, or WSAWaitForMultipleEvents must be supported by the kernel
1153 ret = ep_init(maxevents, flags);
1156 msg(
M_WARN,
"Note: sys_epoll API is unavailable, falling back to poll/select API");
#define ALLOC_ARRAY_CLEAR(dptr, type, n)
#define ALLOC_OBJ_CLEAR(dptr, type)
static bool we_append_event(struct we_set *wes, event_t event, unsigned int rwflags, void *arg)
static struct event_set * event_set_init_simple(int *maxevents, unsigned int flags)
static void we_free(struct event_set *es)
static void we_get_rw_indices(struct we_set *wes, event_t event, int *ri, int *wi)
static void we_del_index(struct we_set *wes, int index)
static int tv_to_ms_timeout(const struct timeval *tv)
static struct event_set * event_set_init_scalable(int *maxevents, unsigned int flags)
static void we_del(struct event_set *es, event_t event)
static int we_wait(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
static void we_ctl(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
static struct event_set * we_init(int *maxevents, unsigned int flags)
struct event_set * event_set_init(int *maxevents, unsigned int flags)
static void we_del_event(struct we_set *wes, event_t event)
static void we_set_event(struct we_set *wes, int i, event_t event, unsigned int rwflags, void *arg)
static void we_reset(struct event_set *es)
#define EVENT_METHOD_FAST
#define EVENT_METHOD_US_TIMEOUT
void set_cloexec(socket_descriptor_t fd)
static void openvpn_fd_set(socket_descriptor_t fd, fd_set *setp)
static int min_int(int x, int y)
static int max_int(int x, int y)
static SERVICE_STATUS status
static bool check_debug_level(unsigned int level)
void(* ctl)(struct event_set *es, event_t event, unsigned int rwflags, void *arg)
int(* wait)(struct event_set *es, const struct timeval *tv, struct event_set_return *out, int outlen)
void(* del)(struct event_set *es, event_t event)
void(* reset)(struct event_set *es)
void(* free)(struct event_set *es)
struct event_set_return * esr
struct event_set_functions func