1 /* ioset kqueue()/kevent() backend for srvx
2 * Copyright 2008 srvx Development Team
4 * This file is part of srvx.
6 * srvx is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with srvx; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 #include "ioset-impl.h"
25 #ifdef HAVE_SYS_EVENT_H
26 # include <sys/event.h>
31 extern int clock_skew;
35 ioset_kevent_init(void)
42 ioset_kevent_add(struct io_fd *fd)
44 struct kevent changes[2];
48 EV_SET(&changes[nchanges++], fd->fd, EVFILT_READ, EV_ADD, 0, 0, fd);
49 EV_SET(&changes[nchanges++], fd->fd, EVFILT_WRITE, fd_wants_writes(fd) ? EV_ADD : EV_DELETE, 0, 0, fd);
50 res = kevent(kq_fd, changes, nchanges, NULL, 0, NULL);
52 log_module(MAIN_LOG, LOG_ERROR, "kevent() add failed: %s", strerror(errno));
57 ioset_kevent_remove(struct io_fd *fd, int closed)
60 struct kevent changes[2];
64 EV_SET(&changes[nchanges++], fd->fd, EVFILT_READ, EV_DELETE, 0, 0, fd);
65 EV_SET(&changes[nchanges++], fd->fd, EVFILT_WRITE, EV_DELETE, 0, 0, fd);
66 res = kevent(kq_fd, changes, nchanges, NULL, 0, NULL);
68 log_module(MAIN_LOG, LOG_ERROR, "kevent() remove failed: %s", strerror(errno));
74 ioset_kevent_update(struct io_fd *fd)
80 ioset_kevent_cleanup(void)
86 ioset_kevent_loop(struct timeval *timeout)
88 struct kevent events[MAX_EVENTS];
96 /* Try to get events from the kernel. */
98 ts.tv_sec = timeout->tv_sec;
99 ts.tv_nsec = timeout->tv_usec * 1000;
104 res = kevent(kq_fd, NULL, 0, events, MAX_EVENTS, pts);
106 log_module(MAIN_LOG, LOG_ERROR, "kevent() poll failed: %s", strerror(errno));
109 now = time(NULL) + clock_skew;
111 /* Process the events we got. */
112 for (ii = 0; ii < res; ++ii) {
113 is_write = events[ii].filter == EVFILT_WRITE;
114 is_read = events[ii].filter == EVFILT_READ;
115 ioset_events(events[ii].udata, is_read, is_write);
121 struct io_engine io_engine_kevent = {
123 .init = ioset_kevent_init,
124 .add = ioset_kevent_add,
125 .remove = ioset_kevent_remove,
126 .update = ioset_kevent_update,
127 .loop = ioset_kevent_loop,
128 .cleanup = ioset_kevent_cleanup,