2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
8 * Copyright (C) 2002-2009 OpenVPN Technologies, Inc. <sales@openvpn.net>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program (see the file COPYING included with this
21 * distribution); if not, write to the Free Software Foundation, Inc.,
22 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
35 * Some OSes will prefer select() over poll()
36 * when both are available.
38 #if defined(TARGET_DARWIN)
39 #define SELECT_PREFERRED_OVER_POLL
43 * All non-windows OSes are assumed to have select()
52 * This should be set to the highest file descriptor
53 * which can be used in one of the FD_ macros.
56 #define SELECT_MAX_FDS FD_SETSIZE
58 #define SELECT_MAX_FDS 256
62 tv_to_ms_timeout (const struct timeval
*tv
)
64 if (tv
->tv_sec
== 0 && tv
->tv_usec
== 0)
67 return max_int (tv
->tv_sec
* 1000 + (tv
->tv_usec
+ 500) / 1000, 1);
74 struct event_set_functions func
;
77 struct event_set_return
*esr
;
83 we_set_event (struct we_set
*wes
, int i
, event_t event
, unsigned int rwflags
, void *arg
)
85 ASSERT (i
>= 0 && i
< wes
->capacity
);
87 if (rwflags
== EVENT_READ
)
89 ASSERT (event
->read
!= NULL
);
90 wes
->events
[i
] = event
->read
;
92 else if (rwflags
== EVENT_WRITE
)
94 ASSERT (event
->write
!= NULL
);
95 wes
->events
[i
] = event
->write
;
98 msg (M_FATAL
, "fatal error in we_set_events: rwflags=%d", rwflags
);
100 wes
->esr
[i
].rwflags
= rwflags
;
101 wes
->esr
[i
].arg
= arg
;
105 we_append_event (struct we_set
*wes
, event_t event
, unsigned int rwflags
, void *arg
)
107 if (rwflags
& EVENT_WRITE
)
109 if (wes
->n_events
< wes
->capacity
)
111 we_set_event (wes
, wes
->n_events
, event
, EVENT_WRITE
, arg
);
117 if (rwflags
& EVENT_READ
)
119 if (wes
->n_events
< wes
->capacity
)
121 we_set_event (wes
, wes
->n_events
, event
, EVENT_READ
, arg
);
131 we_del_event (struct we_set
*wes
, event_t event
)
134 const int len
= wes
->n_events
;
136 for (i
= 0; i
< len
; ++i
)
138 const HANDLE h
= wes
->events
[i
];
139 if (h
== event
->read
|| h
== event
->write
)
145 wes
->events
[j
] = wes
->events
[i
];
146 wes
->esr
[j
] = wes
->esr
[i
];
154 we_del_index (struct we_set
*wes
, int index
)
157 ASSERT (index
>= 0 && index
< wes
->n_events
);
158 for (i
= index
; i
< wes
->n_events
- 1; ++i
)
160 wes
->events
[i
] = wes
->events
[i
+1];
161 wes
->esr
[i
] = wes
->esr
[i
+1];
167 we_get_rw_indices (struct we_set
*wes
, event_t event
, int *ri
, int *wi
)
171 for (i
= 0; i
< wes
->n_events
; ++i
)
173 const HANDLE h
= wes
->events
[i
];
174 if (h
== event
->read
)
179 else if (h
== event
->write
)
188 we_free (struct event_set
*es
)
190 struct we_set
*wes
= (struct we_set
*) es
;
197 we_reset (struct event_set
*es
)
199 struct we_set
*wes
= (struct we_set
*) es
;
205 we_del (struct event_set
*es
, event_t event
)
207 struct we_set
*wes
= (struct we_set
*) es
;
209 we_del_event (wes
, event
);
213 we_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
215 struct we_set
*wes
= (struct we_set
*) es
;
217 dmsg (D_EVENT_WAIT
, "WE_CTL n=%d ev=0x%08x rwflags=0x%04x arg=" ptr_format
,
225 if (!we_append_event (wes
, event
, rwflags
, arg
))
234 we_get_rw_indices (wes
, event
, &ri
, &wi
);
253 we_del_index (wes
, one
);
256 we_del_event (wes
, event
);
266 if (!we_append_event (wes
, event
, EVENT_READ
, arg
))
270 we_set_event (wes
, one
, event
, EVENT_READ
, arg
);
273 we_del_index (wes
, wi
);
283 if (!we_append_event (wes
, event
, EVENT_WRITE
, arg
))
287 we_set_event (wes
, one
, event
, EVENT_WRITE
, arg
);
290 we_del_index (wes
, ri
);
296 case EVENT_READ
|EVENT_WRITE
:
300 if (!we_append_event (wes
, event
, EVENT_READ
|EVENT_WRITE
, arg
))
307 if (!we_append_event (wes
, event
, EVENT_READ
, arg
))
312 if (!we_append_event (wes
, event
, EVENT_WRITE
, arg
))
325 msg (M_FATAL
, "fatal error in we_ctl: rwflags=%d", rwflags
);
331 msg (D_EVENT_ERRORS
, "Error: Windows resource limit WSA_MAXIMUM_WAIT_EVENTS (%d) has been exceeded", WSA_MAXIMUM_WAIT_EVENTS
);
335 we_wait (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
337 struct we_set
*wes
= (struct we_set
*) es
;
338 const int timeout
= tv_to_ms_timeout (tv
);
341 dmsg (D_EVENT_WAIT
, "WE_WAIT enter n=%d to=%d", wes
->n_events
, timeout
);
344 if (check_debug_level (D_EVENT_WAIT
)) {
346 for (i
= 0; i
< wes
->n_events
; ++i
)
347 dmsg (D_EVENT_WAIT
, "[%d] ev=0x%08x rwflags=0x%04x arg=" ptr_format
,
349 (unsigned int)wes
->events
[i
],
351 (ptr_type
)wes
->esr
[i
].arg
);
356 * First poll our event list with 0 timeout
358 status
= WSAWaitForMultipleEvents(
359 (DWORD
) wes
->n_events
,
366 * If at least one event is already set, we must
367 * individually poll the whole list.
369 if (status
>= WSA_WAIT_EVENT_0
&& status
< WSA_WAIT_EVENT_0
+ (DWORD
) wes
->n_events
)
373 for (i
= 0; i
< wes
->n_events
; ++i
)
377 if (WaitForSingleObject (wes
->events
[i
], 0) == WAIT_OBJECT_0
)
380 dmsg (D_EVENT_WAIT
, "WE_WAIT leave [%d,%d] rwflags=0x%04x arg=" ptr_format
,
381 i
, j
, out
->rwflags
, (ptr_type
)out
->arg
);
391 * If caller specified timeout > 0, we know at this point
392 * that no events are set, so wait only for the first event
393 * (or timeout) and return at most one event_set_return object.
395 * If caller specified timeout == 0, the second call to
396 * WSAWaitForMultipleEvents would be redundant -- just
397 * return 0 indicating timeout.
400 status
= WSAWaitForMultipleEvents(
401 (DWORD
) wes
->n_events
,
407 if (outlen
>= 1 && status
>= WSA_WAIT_EVENT_0
&& status
< WSA_WAIT_EVENT_0
+ (DWORD
) wes
->n_events
)
409 *out
= wes
->esr
[status
- WSA_WAIT_EVENT_0
];
410 dmsg (D_EVENT_WAIT
, "WE_WAIT leave rwflags=0x%04x arg=" ptr_format
,
411 out
->rwflags
, (ptr_type
)out
->arg
);
414 else if (status
== WSA_WAIT_TIMEOUT
)
421 static struct event_set
*
422 we_init (int *maxevents
, unsigned int flags
)
426 dmsg (D_EVENT_WAIT
, "WE_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
428 ALLOC_OBJ_CLEAR (wes
, struct we_set
);
430 /* set dispatch functions */
431 wes
->func
.free
= we_free
;
432 wes
->func
.reset
= we_reset
;
433 wes
->func
.del
= we_del
;
434 wes
->func
.ctl
= we_ctl
;
435 wes
->func
.wait
= we_wait
;
437 if (flags
& EVENT_METHOD_FAST
)
441 /* Figure our event capacity */
442 ASSERT (*maxevents
> 0);
443 wes
->capacity
= min_int (*maxevents
* 2, WSA_MAXIMUM_WAIT_EVENTS
);
444 *maxevents
= min_int (*maxevents
, WSA_MAXIMUM_WAIT_EVENTS
);
446 /* Allocate space for Win32 event handles */
447 ALLOC_ARRAY_CLEAR (wes
->events
, HANDLE
, wes
->capacity
);
449 /* Allocate space for event_set_return objects */
450 ALLOC_ARRAY_CLEAR (wes
->esr
, struct event_set_return
, wes
->capacity
);
452 dmsg (D_EVENT_WAIT
, "WE_INIT maxevents=%d capacity=%d",
453 *maxevents
, wes
->capacity
);
455 return (struct event_set
*) wes
;
464 struct event_set_functions func
;
468 struct epoll_event
*events
;
472 ep_free (struct event_set
*es
)
474 struct ep_set
*eps
= (struct ep_set
*) es
;
481 ep_reset (struct event_set
*es
)
483 const struct ep_set
*eps
= (struct ep_set
*) es
;
488 ep_del (struct event_set
*es
, event_t event
)
490 struct epoll_event ev
;
491 struct ep_set
*eps
= (struct ep_set
*) es
;
493 dmsg (D_EVENT_WAIT
, "EP_DEL ev=%d", (int)event
);
497 epoll_ctl (eps
->epfd
, EPOLL_CTL_DEL
, event
, &ev
);
501 ep_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
503 struct ep_set
*eps
= (struct ep_set
*) es
;
504 struct epoll_event ev
;
509 if (rwflags
& EVENT_READ
)
510 ev
.events
|= EPOLLIN
;
511 if (rwflags
& EVENT_WRITE
)
512 ev
.events
|= EPOLLOUT
;
514 dmsg (D_EVENT_WAIT
, "EP_CTL fd=%d rwflags=0x%04x ev=0x%08x arg=" ptr_format
,
517 (unsigned int)ev
.events
,
518 (ptr_type
)ev
.data
.ptr
);
520 if (epoll_ctl (eps
->epfd
, EPOLL_CTL_MOD
, event
, &ev
) < 0)
524 if (epoll_ctl (eps
->epfd
, EPOLL_CTL_ADD
, event
, &ev
) < 0)
525 msg (M_ERR
, "EVENT: epoll_ctl EPOLL_CTL_ADD failed");
528 msg (M_ERR
, "EVENT: epoll_ctl EPOLL_CTL_MOD failed");
533 ep_wait (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
535 struct ep_set
*eps
= (struct ep_set
*) es
;
538 if (outlen
> eps
->maxevents
)
539 outlen
= eps
->maxevents
;
541 stat
= epoll_wait (eps
->epfd
, eps
->events
, outlen
, tv_to_ms_timeout (tv
));
542 ASSERT (stat
<= outlen
);
547 const struct epoll_event
*ev
= eps
->events
;
548 struct event_set_return
*esr
= out
;
549 for (i
= 0; i
< stat
; ++i
)
552 if (ev
->events
& (EPOLLIN
|EPOLLPRI
|EPOLLERR
|EPOLLHUP
))
553 esr
->rwflags
|= EVENT_READ
;
554 if (ev
->events
& EPOLLOUT
)
555 esr
->rwflags
|= EVENT_WRITE
;
556 esr
->arg
= ev
->data
.ptr
;
557 dmsg (D_EVENT_WAIT
, "EP_WAIT[%d] rwflags=0x%04x ev=0x%08x arg=" ptr_format
,
558 i
, esr
->rwflags
, ev
->events
, (ptr_type
)ev
->data
.ptr
);
566 static struct event_set
*
567 ep_init (int *maxevents
, unsigned int flags
)
572 dmsg (D_EVENT_WAIT
, "EP_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
574 /* open epoll file descriptor */
575 fd
= epoll_create (*maxevents
);
579 ALLOC_OBJ_CLEAR (eps
, struct ep_set
);
581 /* set dispatch functions */
582 eps
->func
.free
= ep_free
;
583 eps
->func
.reset
= ep_reset
;
584 eps
->func
.del
= ep_del
;
585 eps
->func
.ctl
= ep_ctl
;
586 eps
->func
.wait
= ep_wait
;
588 /* fast method ("sort of") corresponds to epoll one-shot */
589 if (flags
& EVENT_METHOD_FAST
)
592 /* allocate space for epoll_wait return */
593 ASSERT (*maxevents
> 0);
594 eps
->maxevents
= *maxevents
;
595 ALLOC_ARRAY_CLEAR (eps
->events
, struct epoll_event
, eps
->maxevents
);
597 /* set epoll control fd */
600 return (struct event_set
*) eps
;
608 struct event_set_functions func
;
610 struct pollfd
*events
;
617 po_free (struct event_set
*es
)
619 struct po_set
*pos
= (struct po_set
*) es
;
626 po_reset (struct event_set
*es
)
628 struct po_set
*pos
= (struct po_set
*) es
;
634 po_del (struct event_set
*es
, event_t event
)
636 struct po_set
*pos
= (struct po_set
*) es
;
639 dmsg (D_EVENT_WAIT
, "PO_DEL ev=%d", (int)event
);
642 for (i
= 0; i
< pos
->n_events
; ++i
)
644 if (pos
->events
[i
].fd
== event
)
647 for (j
= i
; j
< pos
->n_events
- 1; ++j
)
649 pos
->events
[j
] = pos
->events
[j
+1];
650 pos
->args
[j
] = pos
->args
[j
+1];
659 po_set_pollfd_events (struct pollfd
*pfdp
, unsigned int rwflags
)
662 if (rwflags
& EVENT_WRITE
)
663 pfdp
->events
|= POLLOUT
;
664 if (rwflags
& EVENT_READ
)
665 pfdp
->events
|= (POLLIN
|POLLPRI
);
669 po_append_event (struct po_set
*pos
, event_t event
, unsigned int rwflags
, void *arg
)
671 if (pos
->n_events
< pos
->capacity
)
673 struct pollfd
*pfdp
= &pos
->events
[pos
->n_events
];
675 pos
->args
[pos
->n_events
] = arg
;
676 po_set_pollfd_events (pfdp
, rwflags
);
685 po_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
687 struct po_set
*pos
= (struct po_set
*) es
;
689 dmsg (D_EVENT_WAIT
, "PO_CTL rwflags=0x%04x ev=%d arg=" ptr_format
,
690 rwflags
, (int)event
, (ptr_type
)arg
);
694 if (!po_append_event (pos
, event
, rwflags
, arg
))
700 for (i
= 0; i
< pos
->n_events
; ++i
)
702 struct pollfd
*pfdp
= &pos
->events
[i
];
703 if (pfdp
->fd
== event
)
706 po_set_pollfd_events (pfdp
, rwflags
);
710 if (!po_append_event (pos
, event
, rwflags
, arg
))
718 msg (D_EVENT_ERRORS
, "Error: poll: too many I/O wait events");
722 po_wait (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
724 struct po_set
*pos
= (struct po_set
*) es
;
727 stat
= poll (pos
->events
, pos
->n_events
, tv_to_ms_timeout (tv
));
729 ASSERT (stat
<= pos
->n_events
);
734 const struct pollfd
*pfdp
= pos
->events
;
735 for (i
= 0; i
< pos
->n_events
&& j
< outlen
; ++i
)
737 if (pfdp
->revents
& (POLLIN
|POLLPRI
|POLLERR
|POLLHUP
|POLLOUT
))
740 if (pfdp
->revents
& (POLLIN
|POLLPRI
|POLLERR
|POLLHUP
))
741 out
->rwflags
|= EVENT_READ
;
742 if (pfdp
->revents
& POLLOUT
)
743 out
->rwflags
|= EVENT_WRITE
;
744 out
->arg
= pos
->args
[i
];
745 dmsg (D_EVENT_WAIT
, "PO_WAIT[%d,%d] fd=%d rev=0x%08x rwflags=0x%04x arg=" ptr_format
" %s",
746 i
, j
, pfdp
->fd
, pfdp
->revents
, out
->rwflags
, (ptr_type
)out
->arg
, pos
->fast
? "" : "[scalable]");
750 else if (pfdp
->revents
)
752 msg (D_EVENT_ERRORS
, "Error: poll: unknown revents=0x%04x", (unsigned int)pfdp
->revents
);
761 static struct event_set
*
762 po_init (int *maxevents
, unsigned int flags
)
766 dmsg (D_EVENT_WAIT
, "PO_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
768 ALLOC_OBJ_CLEAR (pos
, struct po_set
);
770 /* set dispatch functions */
771 pos
->func
.free
= po_free
;
772 pos
->func
.reset
= po_reset
;
773 pos
->func
.del
= po_del
;
774 pos
->func
.ctl
= po_ctl
;
775 pos
->func
.wait
= po_wait
;
777 if (flags
& EVENT_METHOD_FAST
)
782 /* Figure our event capacity */
783 ASSERT (*maxevents
> 0);
784 pos
->capacity
= *maxevents
;
786 /* Allocate space for pollfd structures to be passed to poll() */
787 ALLOC_ARRAY_CLEAR (pos
->events
, struct pollfd
, pos
->capacity
);
789 /* Allocate space for event_set_return objects */
790 ALLOC_ARRAY_CLEAR (pos
->args
, void *, pos
->capacity
);
792 return (struct event_set
*) pos
;
800 struct event_set_functions func
;
804 void **args
; /* allocated to capacity size */
805 int maxfd
; /* largest fd seen so far, always < capacity */
806 int capacity
; /* fixed largest fd + 1 */
810 se_free (struct event_set
*es
)
812 struct se_set
*ses
= (struct se_set
*) es
;
818 se_reset (struct event_set
*es
)
820 struct se_set
*ses
= (struct se_set
*) es
;
824 dmsg (D_EVENT_WAIT
, "SE_RESET");
826 FD_ZERO (&ses
->readfds
);
827 FD_ZERO (&ses
->writefds
);
828 for (i
= 0; i
<= ses
->maxfd
; ++i
)
834 se_del (struct event_set
*es
, event_t event
)
836 struct se_set
*ses
= (struct se_set
*) es
;
839 dmsg (D_EVENT_WAIT
, "SE_DEL ev=%d", (int)event
);
841 if (event
>= 0 && event
< ses
->capacity
)
843 FD_CLR (event
, &ses
->readfds
);
844 FD_CLR (event
, &ses
->writefds
);
845 ses
->args
[event
] = NULL
;
848 msg (D_EVENT_ERRORS
, "Error: select/se_del: too many I/O wait events");
853 se_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
855 struct se_set
*ses
= (struct se_set
*) es
;
857 dmsg (D_EVENT_WAIT
, "SE_CTL rwflags=0x%04x ev=%d fast=%d cap=%d maxfd=%d arg=" ptr_format
,
858 rwflags
, (int)event
, (int)ses
->fast
, ses
->capacity
, ses
->maxfd
, (ptr_type
)arg
);
860 if (event
>= 0 && event
< ses
->capacity
)
862 ses
->maxfd
= max_int (event
, ses
->maxfd
);
863 ses
->args
[event
] = arg
;
866 if (rwflags
& EVENT_READ
)
867 FD_SET (event
, &ses
->readfds
);
868 if (rwflags
& EVENT_WRITE
)
869 FD_SET (event
, &ses
->writefds
);
873 if (rwflags
& EVENT_READ
)
874 FD_SET (event
, &ses
->readfds
);
876 FD_CLR (event
, &ses
->readfds
);
877 if (rwflags
& EVENT_WRITE
)
878 FD_SET (event
, &ses
->writefds
);
880 FD_CLR (event
, &ses
->writefds
);
885 msg (D_EVENT_ERRORS
, "Error: select: too many I/O wait events, fd=%d cap=%d",
892 se_wait_return (struct se_set
*ses
,
895 struct event_set_return
*out
,
899 for (i
= 0; i
<= ses
->maxfd
&& j
< outlen
; ++i
)
901 const bool r
= FD_ISSET (i
, read
);
902 const bool w
= FD_ISSET (i
, write
);
907 out
->rwflags
|= EVENT_READ
;
909 out
->rwflags
|= EVENT_WRITE
;
910 out
->arg
= ses
->args
[i
];
911 dmsg (D_EVENT_WAIT
, "SE_WAIT[%d,%d] rwflags=0x%04x arg=" ptr_format
,
912 i
, j
, out
->rwflags
, (ptr_type
)out
->arg
);
921 se_wait_fast (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
923 struct se_set
*ses
= (struct se_set
*) es
;
924 struct timeval tv_tmp
= *tv
;
927 dmsg (D_EVENT_WAIT
, "SE_WAIT_FAST maxfd=%d tv=%d/%d",
930 (int)tv_tmp
.tv_usec
);
932 stat
= select (ses
->maxfd
+ 1, &ses
->readfds
, &ses
->writefds
, NULL
, &tv_tmp
);
935 stat
= se_wait_return (ses
, &ses
->readfds
, &ses
->writefds
, out
, outlen
);
941 se_wait_scalable (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
943 struct se_set
*ses
= (struct se_set
*) es
;
944 struct timeval tv_tmp
= *tv
;
945 fd_set read
= ses
->readfds
;
946 fd_set write
= ses
->writefds
;
949 dmsg (D_EVENT_WAIT
, "SE_WAIT_SCALEABLE maxfd=%d tv=%d/%d",
950 ses
->maxfd
, (int)tv_tmp
.tv_sec
, (int)tv_tmp
.tv_usec
);
952 stat
= select (ses
->maxfd
+ 1, &read
, &write
, NULL
, &tv_tmp
);
955 stat
= se_wait_return (ses
, &read
, &write
, out
, outlen
);
960 static struct event_set
*
961 se_init (int *maxevents
, unsigned int flags
)
965 dmsg (D_EVENT_WAIT
, "SE_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
967 ALLOC_OBJ_CLEAR (ses
, struct se_set
);
969 /* set dispatch functions */
970 ses
->func
.free
= se_free
;
971 ses
->func
.reset
= se_reset
;
972 ses
->func
.del
= se_del
;
973 ses
->func
.ctl
= se_ctl
;
974 ses
->func
.wait
= se_wait_scalable
;
976 if (flags
& EVENT_METHOD_FAST
)
979 ses
->func
.wait
= se_wait_fast
;
982 /* Select needs to be passed this value + 1 */
985 /* Set our event capacity */
986 ASSERT (*maxevents
> 0);
987 *maxevents
= min_int (*maxevents
, SELECT_MAX_FDS
);
988 ses
->capacity
= SELECT_MAX_FDS
;
990 /* Allocate space for event_set_return void * args */
991 ALLOC_ARRAY_CLEAR (ses
->args
, void *, ses
->capacity
);
993 return (struct event_set
*) ses
;
997 static struct event_set
*
998 event_set_init_simple (int *maxevents
, unsigned int flags
)
1000 struct event_set
*ret
= NULL
;
1002 ret
= we_init (maxevents
, flags
);
1003 #elif POLL && SELECT
1004 #if 0 /* Define to 1 if EVENT_METHOD_US_TIMEOUT should cause select to be favored over poll */
1005 if (flags
& EVENT_METHOD_US_TIMEOUT
)
1006 ret
= se_init (maxevents
, flags
);
1008 # ifdef SELECT_PREFERRED_OVER_POLL
1010 ret
= se_init (maxevents
, flags
);
1012 ret
= po_init (maxevents
, flags
);
1015 ret
= po_init (maxevents
, flags
);
1017 ret
= se_init (maxevents
, flags
);
1020 ret
= po_init (maxevents
, flags
);
1022 ret
= se_init (maxevents
, flags
);
1024 #error At least one of poll, select, or WSAWaitForMultipleEvents must be supported by the kernel
1030 static struct event_set
*
1031 event_set_init_scalable (int *maxevents
, unsigned int flags
)
1033 struct event_set
*ret
= NULL
;
1035 ret
= ep_init (maxevents
, flags
);
1038 msg (M_WARN
, "Note: sys_epoll API is unavailable, falling back to poll/select API");
1039 ret
= event_set_init_simple (maxevents
, flags
);
1042 ret
= event_set_init_simple (maxevents
, flags
);
1049 event_set_init (int *maxevents
, unsigned int flags
)
1051 if (flags
& EVENT_METHOD_FAST
)
1052 return event_set_init_simple (maxevents
, flags
);
1054 return event_set_init_scalable (maxevents
, flags
);