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 3 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
,