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-2005 OpenVPN Solutions LLC <info@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
26 #include "config-win32.h"
41 * Some OSes will prefer select() over poll()
42 * when both are available.
44 #if defined(TARGET_DARWIN)
45 #define SELECT_PREFERRED_OVER_POLL
49 * All non-windows OSes are assumed to have select()
58 * This should be set to the highest file descriptor
59 * which can be used in one of the FD_ macros.
62 #define SELECT_MAX_FDS FD_SETSIZE
64 #define SELECT_MAX_FDS 256
68 tv_to_ms_timeout (const struct timeval
*tv
)
70 if (tv
->tv_sec
== 0 && tv
->tv_usec
== 0)
73 return max_int (tv
->tv_sec
* 1000 + (tv
->tv_usec
+ 500) / 1000, 1);
80 struct event_set_functions func
;
83 struct event_set_return
*esr
;
89 we_set_event (struct we_set
*wes
, int i
, event_t event
, unsigned int rwflags
, void *arg
)
91 ASSERT (i
>= 0 && i
< wes
->capacity
);
93 if (rwflags
== EVENT_READ
)
95 ASSERT (event
->read
!= NULL
);
96 wes
->events
[i
] = event
->read
;
98 else if (rwflags
== EVENT_WRITE
)
100 ASSERT (event
->write
!= NULL
);
101 wes
->events
[i
] = event
->write
;
104 msg (M_FATAL
, "fatal error in we_set_events: rwflags=%d", rwflags
);
106 wes
->esr
[i
].rwflags
= rwflags
;
107 wes
->esr
[i
].arg
= arg
;
111 we_append_event (struct we_set
*wes
, event_t event
, unsigned int rwflags
, void *arg
)
113 if (rwflags
& EVENT_WRITE
)
115 if (wes
->n_events
< wes
->capacity
)
117 we_set_event (wes
, wes
->n_events
, event
, EVENT_WRITE
, arg
);
123 if (rwflags
& EVENT_READ
)
125 if (wes
->n_events
< wes
->capacity
)
127 we_set_event (wes
, wes
->n_events
, event
, EVENT_READ
, arg
);
137 we_del_event (struct we_set
*wes
, event_t event
)
140 const int len
= wes
->n_events
;
142 for (i
= 0; i
< len
; ++i
)
144 const HANDLE h
= wes
->events
[i
];
145 if (h
== event
->read
|| h
== event
->write
)
151 wes
->events
[j
] = wes
->events
[i
];
152 wes
->esr
[j
] = wes
->esr
[i
];
160 we_del_index (struct we_set
*wes
, int index
)
163 ASSERT (index
>= 0 && index
< wes
->n_events
);
164 for (i
= index
; i
< wes
->n_events
- 1; ++i
)
166 wes
->events
[i
] = wes
->events
[i
+1];
167 wes
->esr
[i
] = wes
->esr
[i
+1];
173 we_get_rw_indices (struct we_set
*wes
, event_t event
, int *ri
, int *wi
)
177 for (i
= 0; i
< wes
->n_events
; ++i
)
179 const HANDLE h
= wes
->events
[i
];
180 if (h
== event
->read
)
185 else if (h
== event
->write
)
194 we_free (struct event_set
*es
)
196 struct we_set
*wes
= (struct we_set
*) es
;
203 we_reset (struct event_set
*es
)
205 struct we_set
*wes
= (struct we_set
*) es
;
211 we_del (struct event_set
*es
, event_t event
)
213 struct we_set
*wes
= (struct we_set
*) es
;
215 we_del_event (wes
, event
);
219 we_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
221 struct we_set
*wes
= (struct we_set
*) es
;
223 dmsg (D_EVENT_WAIT
, "WE_CTL n=%d ev=0x%08x rwflags=0x%04x arg=" ptr_format
,
231 if (!we_append_event (wes
, event
, rwflags
, arg
))
240 we_get_rw_indices (wes
, event
, &ri
, &wi
);
259 we_del_index (wes
, one
);
262 we_del_event (wes
, event
);
272 if (!we_append_event (wes
, event
, EVENT_READ
, arg
))
276 we_set_event (wes
, one
, event
, EVENT_READ
, arg
);
279 we_del_index (wes
, wi
);
289 if (!we_append_event (wes
, event
, EVENT_WRITE
, arg
))
293 we_set_event (wes
, one
, event
, EVENT_WRITE
, arg
);
296 we_del_index (wes
, ri
);
302 case EVENT_READ
|EVENT_WRITE
:
306 if (!we_append_event (wes
, event
, EVENT_READ
|EVENT_WRITE
, arg
))
313 if (!we_append_event (wes
, event
, EVENT_READ
, arg
))
318 if (!we_append_event (wes
, event
, EVENT_WRITE
, arg
))
331 msg (M_FATAL
, "fatal error in we_ctl: rwflags=%d", rwflags
);
337 msg (D_EVENT_ERRORS
, "Error: Windows resource limit WSA_MAXIMUM_WAIT_EVENTS (%d) has been exceeded", WSA_MAXIMUM_WAIT_EVENTS
);
341 we_wait (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
343 struct we_set
*wes
= (struct we_set
*) es
;
344 const int timeout
= tv_to_ms_timeout (tv
);
347 dmsg (D_EVENT_WAIT
, "WE_WAIT enter n=%d to=%d", wes
->n_events
, timeout
);
350 if (check_debug_level (D_EVENT_WAIT
)) {
352 for (i
= 0; i
< wes
->n_events
; ++i
)
353 dmsg (D_EVENT_WAIT
, "[%d] ev=0x%08x rwflags=0x%04x arg=" ptr_format
,
355 (unsigned int)wes
->events
[i
],
357 (ptr_type
)wes
->esr
[i
].arg
);
362 * First poll our event list with 0 timeout
364 status
= WSAWaitForMultipleEvents(
365 (DWORD
) wes
->n_events
,
372 * If at least one event is already set, we must
373 * individually poll the whole list.
375 if (status
>= WSA_WAIT_EVENT_0
&& status
< WSA_WAIT_EVENT_0
+ (DWORD
) wes
->n_events
)
379 for (i
= 0; i
< wes
->n_events
; ++i
)
383 if (WaitForSingleObject (wes
->events
[i
], 0) == WAIT_OBJECT_0
)
386 dmsg (D_EVENT_WAIT
, "WE_WAIT leave [%d,%d] rwflags=0x%04x arg=" ptr_format
,
387 i
, j
, out
->rwflags
, (ptr_type
)out
->arg
);
397 * If caller specified timeout > 0, we know at this point
398 * that no events are set, so wait only for the first event
399 * (or timeout) and return at most one event_set_return object.
401 * If caller specified timeout == 0, the second call to
402 * WSAWaitForMultipleEvents would be redundant -- just
403 * return 0 indicating timeout.
406 status
= WSAWaitForMultipleEvents(
407 (DWORD
) wes
->n_events
,
413 if (outlen
>= 1 && status
>= WSA_WAIT_EVENT_0
&& status
< WSA_WAIT_EVENT_0
+ (DWORD
) wes
->n_events
)
415 *out
= wes
->esr
[status
- WSA_WAIT_EVENT_0
];
416 dmsg (D_EVENT_WAIT
, "WE_WAIT leave rwflags=0x%04x arg=" ptr_format
,
417 out
->rwflags
, (ptr_type
)out
->arg
);
420 else if (status
== WSA_WAIT_TIMEOUT
)
427 static struct event_set
*
428 we_init (int *maxevents
, unsigned int flags
)
432 dmsg (D_EVENT_WAIT
, "WE_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
434 ALLOC_OBJ_CLEAR (wes
, struct we_set
);
436 /* set dispatch functions */
437 wes
->func
.free
= we_free
;
438 wes
->func
.reset
= we_reset
;
439 wes
->func
.del
= we_del
;
440 wes
->func
.ctl
= we_ctl
;
441 wes
->func
.wait
= we_wait
;
443 if (flags
& EVENT_METHOD_FAST
)
447 /* Figure our event capacity */
448 ASSERT (*maxevents
> 0);
449 wes
->capacity
= min_int (*maxevents
* 2, WSA_MAXIMUM_WAIT_EVENTS
);
450 *maxevents
= min_int (*maxevents
, WSA_MAXIMUM_WAIT_EVENTS
);
452 /* Allocate space for Win32 event handles */
453 ALLOC_ARRAY_CLEAR (wes
->events
, HANDLE
, wes
->capacity
);
455 /* Allocate space for event_set_return objects */
456 ALLOC_ARRAY_CLEAR (wes
->esr
, struct event_set_return
, wes
->capacity
);
458 dmsg (D_EVENT_WAIT
, "WE_INIT maxevents=%d capacity=%d",
459 *maxevents
, wes
->capacity
);
461 return (struct event_set
*) wes
;
470 struct event_set_functions func
;
474 struct epoll_event
*events
;
478 ep_free (struct event_set
*es
)
480 struct ep_set
*eps
= (struct ep_set
*) es
;
487 ep_reset (struct event_set
*es
)
489 const struct ep_set
*eps
= (struct ep_set
*) es
;
494 ep_del (struct event_set
*es
, event_t event
)
496 struct epoll_event ev
;
497 struct ep_set
*eps
= (struct ep_set
*) es
;
499 dmsg (D_EVENT_WAIT
, "EP_DEL ev=%d", (int)event
);
503 epoll_ctl (eps
->epfd
, EPOLL_CTL_DEL
, event
, &ev
);
507 ep_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
509 struct ep_set
*eps
= (struct ep_set
*) es
;
510 struct epoll_event ev
;
515 if (rwflags
& EVENT_READ
)
516 ev
.events
|= EPOLLIN
;
517 if (rwflags
& EVENT_WRITE
)
518 ev
.events
|= EPOLLOUT
;
520 dmsg (D_EVENT_WAIT
, "EP_CTL fd=%d rwflags=0x%04x ev=0x%08x arg=" ptr_format
,
523 (unsigned int)ev
.events
,
524 (ptr_type
)ev
.data
.ptr
);
526 if (epoll_ctl (eps
->epfd
, EPOLL_CTL_MOD
, event
, &ev
) < 0)
530 if (epoll_ctl (eps
->epfd
, EPOLL_CTL_ADD
, event
, &ev
) < 0)
531 msg (M_ERR
, "EVENT: epoll_ctl EPOLL_CTL_ADD failed");
534 msg (M_ERR
, "EVENT: epoll_ctl EPOLL_CTL_MOD failed");
539 ep_wait (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
541 struct ep_set
*eps
= (struct ep_set
*) es
;
544 if (outlen
> eps
->maxevents
)
545 outlen
= eps
->maxevents
;
547 stat
= epoll_wait (eps
->epfd
, eps
->events
, outlen
, tv_to_ms_timeout (tv
));
548 ASSERT (stat
<= outlen
);
553 const struct epoll_event
*ev
= eps
->events
;
554 struct event_set_return
*esr
= out
;
555 for (i
= 0; i
< stat
; ++i
)
558 if (ev
->events
& (EPOLLIN
|EPOLLPRI
|EPOLLERR
))
559 esr
->rwflags
|= EVENT_READ
;
560 if (ev
->events
& EPOLLOUT
)
561 esr
->rwflags
|= EVENT_WRITE
;
562 esr
->arg
= ev
->data
.ptr
;
563 dmsg (D_EVENT_WAIT
, "EP_WAIT[%d] rwflags=0x%04x ev=0x%08x arg=" ptr_format
,
564 i
, esr
->rwflags
, ev
->events
, (ptr_type
)ev
->data
.ptr
);
572 static struct event_set
*
573 ep_init (int *maxevents
, unsigned int flags
)
578 dmsg (D_EVENT_WAIT
, "EP_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
580 /* open epoll file descriptor */
581 fd
= epoll_create (*maxevents
);
585 ALLOC_OBJ_CLEAR (eps
, struct ep_set
);
587 /* set dispatch functions */
588 eps
->func
.free
= ep_free
;
589 eps
->func
.reset
= ep_reset
;
590 eps
->func
.del
= ep_del
;
591 eps
->func
.ctl
= ep_ctl
;
592 eps
->func
.wait
= ep_wait
;
594 /* fast method ("sort of") corresponds to epoll one-shot */
595 if (flags
& EVENT_METHOD_FAST
)
598 /* allocate space for epoll_wait return */
599 ASSERT (*maxevents
> 0);
600 eps
->maxevents
= *maxevents
;
601 ALLOC_ARRAY_CLEAR (eps
->events
, struct epoll_event
, eps
->maxevents
);
603 /* set epoll control fd */
606 return (struct event_set
*) eps
;
614 struct event_set_functions func
;
616 struct pollfd
*events
;
623 po_free (struct event_set
*es
)
625 struct po_set
*pos
= (struct po_set
*) es
;
632 po_reset (struct event_set
*es
)
634 struct po_set
*pos
= (struct po_set
*) es
;
640 po_del (struct event_set
*es
, event_t event
)
642 struct po_set
*pos
= (struct po_set
*) es
;
645 dmsg (D_EVENT_WAIT
, "PO_DEL ev=%d", (int)event
);
648 for (i
= 0; i
< pos
->n_events
; ++i
)
650 if (pos
->events
[i
].fd
== event
)
653 for (j
= i
; j
< pos
->n_events
- 1; ++j
)
655 pos
->events
[j
] = pos
->events
[j
+1];
656 pos
->args
[j
] = pos
->args
[j
+1];
665 po_set_pollfd_events (struct pollfd
*pfdp
, unsigned int rwflags
)
668 if (rwflags
& EVENT_WRITE
)
669 pfdp
->events
|= POLLOUT
;
670 if (rwflags
& EVENT_READ
)
671 pfdp
->events
|= (POLLIN
|POLLPRI
);
675 po_append_event (struct po_set
*pos
, event_t event
, unsigned int rwflags
, void *arg
)
677 if (pos
->n_events
< pos
->capacity
)
679 struct pollfd
*pfdp
= &pos
->events
[pos
->n_events
];
681 pos
->args
[pos
->n_events
] = arg
;
682 po_set_pollfd_events (pfdp
, rwflags
);
691 po_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
693 struct po_set
*pos
= (struct po_set
*) es
;
695 dmsg (D_EVENT_WAIT
, "PO_CTL rwflags=0x%04x ev=%d arg=" ptr_format
,
696 rwflags
, (int)event
, (ptr_type
)arg
);
700 if (!po_append_event (pos
, event
, rwflags
, arg
))
706 for (i
= 0; i
< pos
->n_events
; ++i
)
708 struct pollfd
*pfdp
= &pos
->events
[i
];
709 if (pfdp
->fd
== event
)
712 po_set_pollfd_events (pfdp
, rwflags
);
716 if (!po_append_event (pos
, event
, rwflags
, arg
))
724 msg (D_EVENT_ERRORS
, "Error: poll: too many I/O wait events");
728 po_wait (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
730 struct po_set
*pos
= (struct po_set
*) es
;
733 stat
= poll (pos
->events
, pos
->n_events
, tv_to_ms_timeout (tv
));
735 ASSERT (stat
<= pos
->n_events
);
740 const struct pollfd
*pfdp
= pos
->events
;
741 for (i
= 0; i
< pos
->n_events
&& j
< outlen
; ++i
)
743 if (pfdp
->revents
& (POLLIN
|POLLPRI
|POLLERR
|POLLHUP
|POLLOUT
))
746 if (pfdp
->revents
& (POLLIN
|POLLPRI
|POLLERR
|POLLHUP
))
747 out
->rwflags
|= EVENT_READ
;
748 if (pfdp
->revents
& POLLOUT
)
749 out
->rwflags
|= EVENT_WRITE
;
750 out
->arg
= pos
->args
[i
];
751 dmsg (D_EVENT_WAIT
, "PO_WAIT[%d,%d] fd=%d rev=0x%08x rwflags=0x%04x arg=" ptr_format
" %s",
752 i
, j
, pfdp
->fd
, pfdp
->revents
, out
->rwflags
, (ptr_type
)out
->arg
, pos
->fast
? "" : "[scalable]");
756 else if (pfdp
->revents
)
758 msg (D_EVENT_ERRORS
, "Error: poll: unknown revents=0x%04x", (unsigned int)pfdp
->revents
);
767 static struct event_set
*
768 po_init (int *maxevents
, unsigned int flags
)
772 dmsg (D_EVENT_WAIT
, "PO_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
774 ALLOC_OBJ_CLEAR (pos
, struct po_set
);
776 /* set dispatch functions */
777 pos
->func
.free
= po_free
;
778 pos
->func
.reset
= po_reset
;
779 pos
->func
.del
= po_del
;
780 pos
->func
.ctl
= po_ctl
;
781 pos
->func
.wait
= po_wait
;
783 if (flags
& EVENT_METHOD_FAST
)
788 /* Figure our event capacity */
789 ASSERT (*maxevents
> 0);
790 pos
->capacity
= *maxevents
;
792 /* Allocate space for pollfd structures to be passed to poll() */
793 ALLOC_ARRAY_CLEAR (pos
->events
, struct pollfd
, pos
->capacity
);
795 /* Allocate space for event_set_return objects */
796 ALLOC_ARRAY_CLEAR (pos
->args
, void *, pos
->capacity
);
798 return (struct event_set
*) pos
;
806 struct event_set_functions func
;
810 void **args
; /* allocated to capacity size */
811 int maxfd
; /* largest fd seen so far, always < capacity */
812 int capacity
; /* fixed largest fd + 1 */
816 se_free (struct event_set
*es
)
818 struct se_set
*ses
= (struct se_set
*) es
;
824 se_reset (struct event_set
*es
)
826 struct se_set
*ses
= (struct se_set
*) es
;
830 dmsg (D_EVENT_WAIT
, "SE_RESET");
832 FD_ZERO (&ses
->readfds
);
833 FD_ZERO (&ses
->writefds
);
834 for (i
= 0; i
<= ses
->maxfd
; ++i
)
840 se_del (struct event_set
*es
, event_t event
)
842 struct se_set
*ses
= (struct se_set
*) es
;
845 dmsg (D_EVENT_WAIT
, "SE_DEL ev=%d", (int)event
);
847 if (event
>= 0 && event
< ses
->capacity
)
849 FD_CLR (event
, &ses
->readfds
);
850 FD_CLR (event
, &ses
->writefds
);
851 ses
->args
[event
] = NULL
;
854 msg (D_EVENT_ERRORS
, "Error: select/se_del: too many I/O wait events");
859 se_ctl (struct event_set
*es
, event_t event
, unsigned int rwflags
, void *arg
)
861 struct se_set
*ses
= (struct se_set
*) es
;
863 dmsg (D_EVENT_WAIT
, "SE_CTL rwflags=0x%04x ev=%d fast=%d cap=%d maxfd=%d arg=" ptr_format
,
864 rwflags
, (int)event
, (int)ses
->fast
, ses
->capacity
, ses
->maxfd
, (ptr_type
)arg
);
866 if (event
>= 0 && event
< ses
->capacity
)
868 ses
->maxfd
= max_int (event
, ses
->maxfd
);
869 ses
->args
[event
] = arg
;
872 if (rwflags
& EVENT_READ
)
873 FD_SET (event
, &ses
->readfds
);
874 if (rwflags
& EVENT_WRITE
)
875 FD_SET (event
, &ses
->writefds
);
879 if (rwflags
& EVENT_READ
)
880 FD_SET (event
, &ses
->readfds
);
882 FD_CLR (event
, &ses
->readfds
);
883 if (rwflags
& EVENT_WRITE
)
884 FD_SET (event
, &ses
->writefds
);
886 FD_CLR (event
, &ses
->writefds
);
891 msg (D_EVENT_ERRORS
, "Error: select: too many I/O wait events, fd=%d cap=%d",
898 se_wait_return (struct se_set
*ses
,
901 struct event_set_return
*out
,
905 for (i
= 0; i
<= ses
->maxfd
&& j
< outlen
; ++i
)
907 const bool r
= FD_ISSET (i
, read
);
908 const bool w
= FD_ISSET (i
, write
);
913 out
->rwflags
|= EVENT_READ
;
915 out
->rwflags
|= EVENT_WRITE
;
916 out
->arg
= ses
->args
[i
];
917 dmsg (D_EVENT_WAIT
, "SE_WAIT[%d,%d] rwflags=0x%04x arg=" ptr_format
,
918 i
, j
, out
->rwflags
, (ptr_type
)out
->arg
);
927 se_wait_fast (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
929 struct se_set
*ses
= (struct se_set
*) es
;
930 struct timeval tv_tmp
= *tv
;
933 dmsg (D_EVENT_WAIT
, "SE_WAIT_FAST maxfd=%d tv=%d/%d",
936 (int)tv_tmp
.tv_usec
);
938 stat
= select (ses
->maxfd
+ 1, &ses
->readfds
, &ses
->writefds
, NULL
, &tv_tmp
);
941 stat
= se_wait_return (ses
, &ses
->readfds
, &ses
->writefds
, out
, outlen
);
947 se_wait_scalable (struct event_set
*es
, const struct timeval
*tv
, struct event_set_return
*out
, int outlen
)
949 struct se_set
*ses
= (struct se_set
*) es
;
950 struct timeval tv_tmp
= *tv
;
951 fd_set read
= ses
->readfds
;
952 fd_set write
= ses
->writefds
;
955 dmsg (D_EVENT_WAIT
, "SE_WAIT_SCALEABLE maxfd=%d tv=%d/%d",
956 ses
->maxfd
, (int)tv_tmp
.tv_sec
, (int)tv_tmp
.tv_usec
);
958 stat
= select (ses
->maxfd
+ 1, &read
, &write
, NULL
, &tv_tmp
);
961 stat
= se_wait_return (ses
, &read
, &write
, out
, outlen
);
966 static struct event_set
*
967 se_init (int *maxevents
, unsigned int flags
)
971 dmsg (D_EVENT_WAIT
, "SE_INIT maxevents=%d flags=0x%08x", *maxevents
, flags
);
973 ALLOC_OBJ_CLEAR (ses
, struct se_set
);
975 /* set dispatch functions */
976 ses
->func
.free
= se_free
;
977 ses
->func
.reset
= se_reset
;
978 ses
->func
.del
= se_del
;
979 ses
->func
.ctl
= se_ctl
;
980 ses
->func
.wait
= se_wait_scalable
;
982 if (flags
& EVENT_METHOD_FAST
)
985 ses
->func
.wait
= se_wait_fast
;
988 /* Select needs to be passed this value + 1 */
991 /* Set our event capacity */
992 ASSERT (*maxevents
> 0);
993 *maxevents
= min_int (*maxevents
, SELECT_MAX_FDS
);
994 ses
->capacity
= SELECT_MAX_FDS
;
996 /* Allocate space for event_set_return void * args */
997 ALLOC_ARRAY_CLEAR (ses
->args
, void *, ses
->capacity
);
999 return (struct event_set
*) ses
;
1003 static struct event_set
*
1004 event_set_init_simple (int *maxevents
, unsigned int flags
)
1006 struct event_set
*ret
= NULL
;
1008 ret
= we_init (maxevents
, flags
);
1009 #elif POLL && SELECT
1010 #if 0 /* Define to 1 if EVENT_METHOD_US_TIMEOUT should cause select to be favored over poll */
1011 if (flags
& EVENT_METHOD_US_TIMEOUT
)
1012 ret
= se_init (maxevents
, flags
);
1014 # ifdef SELECT_PREFERRED_OVER_POLL
1016 ret
= se_init (maxevents
, flags
);
1018 ret
= po_init (maxevents
, flags
);
1021 ret
= po_init (maxevents
, flags
);
1023 ret
= se_init (maxevents
, flags
);
1026 ret
= po_init (maxevents
, flags
);
1028 ret
= se_init (maxevents
, flags
);
1030 #error At least one of poll, select, or WSAWaitForMultipleEvents must be supported by the kernel
1036 static struct event_set
*
1037 event_set_init_scalable (int *maxevents
, unsigned int flags
)
1039 struct event_set
*ret
= NULL
;
1041 ret
= ep_init (maxevents
, flags
);
1044 msg (M_WARN
, "Note: sys_epoll API is unavailable, falling back to poll/select API");
1045 ret
= event_set_init_simple (maxevents
, flags
);
1048 ret
= event_set_init_simple (maxevents
, flags
);
1055 event_set_init (int *maxevents
, unsigned int flags
)
1057 if (flags
& EVENT_METHOD_FAST
)
1058 return event_set_init_simple (maxevents
, flags
);
1060 return event_set_init_scalable (maxevents
, flags
);