svn cleanup
[anytun.git] / openvpn / event.c
blob0d2c0961aa27934ca198e16a6ac5e600d1e2d97d
1 /*
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
6 * packet compression.
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
25 #ifdef WIN32
26 #include "config-win32.h"
27 #else
28 #include "config.h"
29 #endif
31 #include "syshead.h"
33 #include "buffer.h"
34 #include "error.h"
35 #include "integer.h"
36 #include "event.h"
38 #include "memdbg.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
46 #endif
49 * All non-windows OSes are assumed to have select()
51 #ifdef WIN32
52 #define SELECT 0
53 #else
54 #define SELECT 1
55 #endif
58 * This should be set to the highest file descriptor
59 * which can be used in one of the FD_ macros.
61 #ifdef FD_SETSIZE
62 #define SELECT_MAX_FDS FD_SETSIZE
63 #else
64 #define SELECT_MAX_FDS 256
65 #endif
67 static inline int
68 tv_to_ms_timeout (const struct timeval *tv)
70 if (tv->tv_sec == 0 && tv->tv_usec == 0)
71 return 0;
72 else
73 return max_int (tv->tv_sec * 1000 + (tv->tv_usec + 500) / 1000, 1);
76 #ifdef WIN32
78 struct we_set
80 struct event_set_functions func;
81 bool fast;
82 HANDLE *events;
83 struct event_set_return *esr;
84 int n_events;
85 int capacity;
88 static inline void
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;
103 else
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;
110 static inline bool
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);
118 ++wes->n_events;
120 else
121 return false;
123 if (rwflags & EVENT_READ)
125 if (wes->n_events < wes->capacity)
127 we_set_event (wes, wes->n_events, event, EVENT_READ, arg);
128 ++wes->n_events;
130 else
131 return false;
133 return true;
136 static void
137 we_del_event (struct we_set *wes, event_t event)
139 int i, j = 0;
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)
146 --wes->n_events;
147 else
149 if (i != j)
151 wes->events[j] = wes->events[i];
152 wes->esr[j] = wes->esr[i];
154 ++j;
159 static void
160 we_del_index (struct we_set *wes, int index)
162 int i;
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];
169 --wes->n_events;
172 static void
173 we_get_rw_indices (struct we_set *wes, event_t event, int *ri, int *wi)
175 int i;
176 *ri = *wi = -1;
177 for (i = 0; i < wes->n_events; ++i)
179 const HANDLE h = wes->events[i];
180 if (h == event->read)
182 ASSERT (*ri == -1);
183 *ri = i;
185 else if (h == event->write)
187 ASSERT (*wi == -1);
188 *wi = i;
193 static void
194 we_free (struct event_set *es)
196 struct we_set *wes = (struct we_set *) es;
197 free (wes->events);
198 free (wes->esr);
199 free (wes);
202 static void
203 we_reset (struct event_set *es)
205 struct we_set *wes = (struct we_set *) es;
206 ASSERT (wes->fast);
207 wes->n_events = 0;
210 static void
211 we_del (struct event_set *es, event_t event)
213 struct we_set *wes = (struct we_set *) es;
214 ASSERT (!wes->fast);
215 we_del_event (wes, event);
218 static void
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,
224 wes->n_events,
225 (unsigned int)event,
226 rwflags,
227 (ptr_type)arg);
229 if (wes->fast)
231 if (!we_append_event (wes, event, rwflags, arg))
232 goto err;
234 else
236 int ri, wi;
237 int one = -1;
238 int n = 0;
240 we_get_rw_indices (wes, event, &ri, &wi);
241 if (wi >= 0)
243 one = wi;
244 ++n;
246 if (ri >= 0)
248 one = ri;
249 ++n;
251 switch (rwflags)
253 case 0:
254 switch (n)
256 case 0:
257 break;
258 case 1:
259 we_del_index (wes, one);
260 break;
261 case 2:
262 we_del_event (wes, event);
263 break;
264 default:
265 ASSERT (0);
267 break;
268 case EVENT_READ:
269 switch (n)
271 case 0:
272 if (!we_append_event (wes, event, EVENT_READ, arg))
273 goto err;
274 break;
275 case 1:
276 we_set_event (wes, one, event, EVENT_READ, arg);
277 break;
278 case 2:
279 we_del_index (wes, wi);
280 break;
281 default:
282 ASSERT (0);
284 break;
285 case EVENT_WRITE:
286 switch (n)
288 case 0:
289 if (!we_append_event (wes, event, EVENT_WRITE, arg))
290 goto err;
291 break;
292 case 1:
293 we_set_event (wes, one, event, EVENT_WRITE, arg);
294 break;
295 case 2:
296 we_del_index (wes, ri);
297 break;
298 default:
299 ASSERT (0);
301 break;
302 case EVENT_READ|EVENT_WRITE:
303 switch (n)
305 case 0:
306 if (!we_append_event (wes, event, EVENT_READ|EVENT_WRITE, arg))
307 goto err;
308 break;
309 case 1:
310 if (ri == -1)
312 ASSERT (wi != -1);
313 if (!we_append_event (wes, event, EVENT_READ, arg))
314 goto err;
316 else if (wi == -1)
318 if (!we_append_event (wes, event, EVENT_WRITE, arg))
319 goto err;
321 else
322 ASSERT (0);
323 break;
324 case 2:
325 break;
326 default:
327 ASSERT (0);
329 break;
330 default:
331 msg (M_FATAL, "fatal error in we_ctl: rwflags=%d", rwflags);
334 return;
336 err:
337 msg (D_EVENT_ERRORS, "Error: Windows resource limit WSA_MAXIMUM_WAIT_EVENTS (%d) has been exceeded", WSA_MAXIMUM_WAIT_EVENTS);
340 static int
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);
345 DWORD status;
347 dmsg (D_EVENT_WAIT, "WE_WAIT enter n=%d to=%d", wes->n_events, timeout);
349 #ifdef ENABLE_DEBUG
350 if (check_debug_level (D_EVENT_WAIT)) {
351 int i;
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],
356 wes->esr[i].rwflags,
357 (ptr_type)wes->esr[i].arg);
359 #endif
362 * First poll our event list with 0 timeout
364 status = WSAWaitForMultipleEvents(
365 (DWORD) wes->n_events,
366 wes->events,
367 FALSE,
368 (DWORD) 0,
369 FALSE);
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)
377 int i;
378 int j = 0;
379 for (i = 0; i < wes->n_events; ++i)
381 if (j >= outlen)
382 break;
383 if (WaitForSingleObject (wes->events[i], 0) == WAIT_OBJECT_0)
385 *out = wes->esr[i];
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);
388 ++j;
389 ++out;
392 return j;
394 else
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.
405 if (timeout > 0)
406 status = WSAWaitForMultipleEvents(
407 (DWORD) wes->n_events,
408 wes->events,
409 FALSE,
410 (DWORD) timeout,
411 FALSE);
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);
418 return 1;
420 else if (status == WSA_WAIT_TIMEOUT)
421 return 0;
422 else
423 return -1;
427 static struct event_set *
428 we_init (int *maxevents, unsigned int flags)
430 struct we_set *wes;
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)
444 wes->fast = true;
445 wes->n_events = 0;
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;
464 #endif /* WIN32 */
466 #if EPOLL
468 struct ep_set
470 struct event_set_functions func;
471 bool fast;
472 int epfd;
473 int maxevents;
474 struct epoll_event *events;
477 static void
478 ep_free (struct event_set *es)
480 struct ep_set *eps = (struct ep_set *) es;
481 close (eps->epfd);
482 free (eps->events);
483 free (eps);
486 static void
487 ep_reset (struct event_set *es)
489 const struct ep_set *eps = (struct ep_set *) es;
490 ASSERT (eps->fast);
493 static void
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);
501 ASSERT (!eps->fast);
502 CLEAR (ev);
503 epoll_ctl (eps->epfd, EPOLL_CTL_DEL, event, &ev);
506 static void
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;
512 CLEAR (ev);
514 ev.data.ptr = arg;
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,
521 (int)event,
522 rwflags,
523 (unsigned int)ev.events,
524 (ptr_type)ev.data.ptr);
526 if (epoll_ctl (eps->epfd, EPOLL_CTL_MOD, event, &ev) < 0)
528 if (errno == ENOENT)
530 if (epoll_ctl (eps->epfd, EPOLL_CTL_ADD, event, &ev) < 0)
531 msg (M_ERR, "EVENT: epoll_ctl EPOLL_CTL_ADD failed");
533 else
534 msg (M_ERR, "EVENT: epoll_ctl EPOLL_CTL_MOD failed");
538 static int
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;
542 int stat;
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);
550 if (stat > 0)
552 int i;
553 const struct epoll_event *ev = eps->events;
554 struct event_set_return *esr = out;
555 for (i = 0; i < stat; ++i)
557 esr->rwflags = 0;
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);
565 ++ev;
566 ++esr;
569 return stat;
572 static struct event_set *
573 ep_init (int *maxevents, unsigned int flags)
575 struct ep_set *eps;
576 int fd;
578 dmsg (D_EVENT_WAIT, "EP_INIT maxevents=%d flags=0x%08x", *maxevents, flags);
580 /* open epoll file descriptor */
581 fd = epoll_create (*maxevents);
582 if (fd < 0)
583 return NULL;
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)
596 eps->fast = true;
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 */
604 eps->epfd = fd;
606 return (struct event_set *) eps;
608 #endif /* EPOLL */
610 #if POLL
612 struct po_set
614 struct event_set_functions func;
615 bool fast;
616 struct pollfd *events;
617 void **args;
618 int n_events;
619 int capacity;
622 static void
623 po_free (struct event_set *es)
625 struct po_set *pos = (struct po_set *) es;
626 free (pos->events);
627 free (pos->args);
628 free (pos);
631 static void
632 po_reset (struct event_set *es)
634 struct po_set *pos = (struct po_set *) es;
635 ASSERT (pos->fast);
636 pos->n_events = 0;
639 static void
640 po_del (struct event_set *es, event_t event)
642 struct po_set *pos = (struct po_set *) es;
643 int i;
645 dmsg (D_EVENT_WAIT, "PO_DEL ev=%d", (int)event);
647 ASSERT (!pos->fast);
648 for (i = 0; i < pos->n_events; ++i)
650 if (pos->events[i].fd == event)
652 int j;
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];
658 --pos->n_events;
659 break;
664 static inline void
665 po_set_pollfd_events (struct pollfd *pfdp, unsigned int rwflags)
667 pfdp->events = 0;
668 if (rwflags & EVENT_WRITE)
669 pfdp->events |= POLLOUT;
670 if (rwflags & EVENT_READ)
671 pfdp->events |= (POLLIN|POLLPRI);
674 static inline bool
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];
680 pfdp->fd = event;
681 pos->args[pos->n_events] = arg;
682 po_set_pollfd_events (pfdp, rwflags);
683 ++pos->n_events;
684 return true;
686 else
687 return false;
690 static void
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);
698 if (pos->fast)
700 if (!po_append_event (pos, event, rwflags, arg))
701 goto err;
703 else
705 int i;
706 for (i = 0; i < pos->n_events; ++i)
708 struct pollfd *pfdp = &pos->events[i];
709 if (pfdp->fd == event)
711 pos->args[i] = arg;
712 po_set_pollfd_events (pfdp, rwflags);
713 goto done;
716 if (!po_append_event (pos, event, rwflags, arg))
717 goto err;
720 done:
721 return;
723 err:
724 msg (D_EVENT_ERRORS, "Error: poll: too many I/O wait events");
727 static int
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;
731 int stat;
733 stat = poll (pos->events, pos->n_events, tv_to_ms_timeout (tv));
735 ASSERT (stat <= pos->n_events);
737 if (stat > 0)
739 int i, j=0;
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))
745 out->rwflags = 0;
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]");
753 ++out;
754 ++j;
756 else if (pfdp->revents)
758 msg (D_EVENT_ERRORS, "Error: poll: unknown revents=0x%04x", (unsigned int)pfdp->revents);
760 ++pfdp;
762 return j;
764 return stat;
767 static struct event_set *
768 po_init (int *maxevents, unsigned int flags)
770 struct po_set *pos;
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)
784 pos->fast = true;
786 pos->n_events = 0;
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;
800 #endif /* POLL */
802 #if SELECT
804 struct se_set
806 struct event_set_functions func;
807 bool fast;
808 fd_set readfds;
809 fd_set writefds;
810 void **args; /* allocated to capacity size */
811 int maxfd; /* largest fd seen so far, always < capacity */
812 int capacity; /* fixed largest fd + 1 */
815 static void
816 se_free (struct event_set *es)
818 struct se_set *ses = (struct se_set *) es;
819 free (ses->args);
820 free (ses);
823 static void
824 se_reset (struct event_set *es)
826 struct se_set *ses = (struct se_set *) es;
827 int i;
828 ASSERT (ses->fast);
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)
835 ses->args[i] = NULL;
836 ses->maxfd = -1;
839 static void
840 se_del (struct event_set *es, event_t event)
842 struct se_set *ses = (struct se_set *) es;
843 ASSERT (!ses->fast);
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;
853 else
854 msg (D_EVENT_ERRORS, "Error: select/se_del: too many I/O wait events");
855 return;
858 static void
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;
870 if (ses->fast)
872 if (rwflags & EVENT_READ)
873 FD_SET (event, &ses->readfds);
874 if (rwflags & EVENT_WRITE)
875 FD_SET (event, &ses->writefds);
877 else
879 if (rwflags & EVENT_READ)
880 FD_SET (event, &ses->readfds);
881 else
882 FD_CLR (event, &ses->readfds);
883 if (rwflags & EVENT_WRITE)
884 FD_SET (event, &ses->writefds);
885 else
886 FD_CLR (event, &ses->writefds);
889 else
891 msg (D_EVENT_ERRORS, "Error: select: too many I/O wait events, fd=%d cap=%d",
892 (int) event,
893 ses->capacity);
897 static int
898 se_wait_return (struct se_set *ses,
899 fd_set *read,
900 fd_set *write,
901 struct event_set_return *out,
902 int outlen)
904 int i, j = 0;
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);
909 if (r || w)
911 out->rwflags = 0;
912 if (r)
913 out->rwflags |= EVENT_READ;
914 if (w)
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);
919 ++out;
920 ++j;
923 return j;
926 static int
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;
931 int stat;
933 dmsg (D_EVENT_WAIT, "SE_WAIT_FAST maxfd=%d tv=%d/%d",
934 ses->maxfd,
935 (int)tv_tmp.tv_sec,
936 (int)tv_tmp.tv_usec);
938 stat = select (ses->maxfd + 1, &ses->readfds, &ses->writefds, NULL, &tv_tmp);
940 if (stat > 0)
941 stat = se_wait_return (ses, &ses->readfds, &ses->writefds, out, outlen);
943 return stat;
946 static int
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;
953 int stat;
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);
960 if (stat > 0)
961 stat = se_wait_return (ses, &read, &write, out, outlen);
963 return stat;
966 static struct event_set *
967 se_init (int *maxevents, unsigned int flags)
969 struct se_set *ses;
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)
984 ses->fast = true;
985 ses->func.wait = se_wait_fast;
988 /* Select needs to be passed this value + 1 */
989 ses->maxfd = -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;
1001 #endif /* SELECT */
1003 static struct event_set *
1004 event_set_init_simple (int *maxevents, unsigned int flags)
1006 struct event_set *ret = NULL;
1007 #ifdef WIN32
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);
1013 #endif
1014 # ifdef SELECT_PREFERRED_OVER_POLL
1015 if (!ret)
1016 ret = se_init (maxevents, flags);
1017 if (!ret)
1018 ret = po_init (maxevents, flags);
1019 # else
1020 if (!ret)
1021 ret = po_init (maxevents, flags);
1022 if (!ret)
1023 ret = se_init (maxevents, flags);
1024 # endif
1025 #elif POLL
1026 ret = po_init (maxevents, flags);
1027 #elif SELECT
1028 ret = se_init (maxevents, flags);
1029 #else
1030 #error At least one of poll, select, or WSAWaitForMultipleEvents must be supported by the kernel
1031 #endif
1032 ASSERT (ret);
1033 return ret;
1036 static struct event_set *
1037 event_set_init_scalable (int *maxevents, unsigned int flags)
1039 struct event_set *ret = NULL;
1040 #if EPOLL
1041 ret = ep_init (maxevents, flags);
1042 if (!ret)
1044 msg (M_WARN, "Note: sys_epoll API is unavailable, falling back to poll/select API");
1045 ret = event_set_init_simple (maxevents, flags);
1047 #else
1048 ret = event_set_init_simple (maxevents, flags);
1049 #endif
1050 ASSERT (ret);
1051 return ret;
1054 struct event_set *
1055 event_set_init (int *maxevents, unsigned int flags)
1057 if (flags & EVENT_METHOD_FAST)
1058 return event_set_init_simple (maxevents, flags);
1059 else
1060 return event_set_init_scalable (maxevents, flags);