diff options
author | Olaf van der Spek <olafvdspek@gmail.com> | 2010-08-23 21:41:54 +0000 |
---|---|---|
committer | Olaf van der Spek <olafvdspek@gmail.com> | 2010-08-23 21:41:54 +0000 |
commit | a85840baef48307ba44719ae44bbb0ca801c30a2 (patch) | |
tree | fdfdb1aefa733b99259eae4618de831940241d32 /src/fdevent_freebsd_kqueue.c | |
parent | b0a9856092499507b786855095a89975c1f9ce35 (diff) | |
download | lighttpd-a85840baef48307ba44719ae44bbb0ca801c30a2.tar.gz |
Upstream 1.4.28
Diffstat (limited to 'src/fdevent_freebsd_kqueue.c')
-rw-r--r-- | src/fdevent_freebsd_kqueue.c | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/src/fdevent_freebsd_kqueue.c b/src/fdevent_freebsd_kqueue.c index b4e862c..0f53a2a 100644 --- a/src/fdevent_freebsd_kqueue.c +++ b/src/fdevent_freebsd_kqueue.c @@ -22,20 +22,31 @@ static void fdevent_freebsd_kqueue_free(fdevents *ev) { } static int fdevent_freebsd_kqueue_event_del(fdevents *ev, int fde_ndx, int fd) { - int ret; + int ret, n = 0; struct kevent kev[2]; struct timespec ts; + int oevents; if (fde_ndx < 0) return -1; - EV_SET(&kev[0], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); - EV_SET(&kev[1], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + oevents = ev->fdarray[fd]->events; + + if (oevents & FDEVENT_IN) { + EV_SET(&kev[n], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + n++; + } + if (oevents & FDEVENT_OUT) { + EV_SET(&kev[n], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + n++; + } + + if (0 == n) return -1; ts.tv_sec = 0; ts.tv_nsec = 0; ret = kevent(ev->kq_fd, - &kev, 2, + &kev, n, NULL, 0, &ts); @@ -49,28 +60,46 @@ static int fdevent_freebsd_kqueue_event_del(fdevents *ev, int fde_ndx, int fd) { return -1; } -static int fdevent_freebsd_kqueue_event_add(fdevents *ev, int fde_ndx, int fd, int events) { - int filter, ret; - struct kevent kev; +static int fdevent_freebsd_kqueue_event_set(fdevents *ev, int fde_ndx, int fd, int events) { + int ret, n = 0; + struct kevent kev[2]; struct timespec ts; + int oevents = ev->fdarray[fd]->events; + int addevents = events & ~oevents; + int delevents = ~events & oevents; UNUSED(fde_ndx); - filter = (events & FDEVENT_IN) ? EVFILT_READ : EVFILT_WRITE; + if (events == oevents) return fd; + + if (addevents & FDEVENT_IN) { + EV_SET(&kev[n], fd, EVFILT_READ, EV_ADD|EV_CLEAR, 0, 0, NULL); + n++; + } else if (delevents & FDEVENT_IN) { + EV_SET(&kev[n], fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + n++; + } + if (addevents & FDEVENT_OUT) { + EV_SET(&kev[n], fd, EVFILT_WRITE, EV_ADD|EV_CLEAR, 0, 0, NULL); + n++; + } else if (delevents & FDEVENT_OUT) { + EV_SET(&kev[n], fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + n++; + } - EV_SET(&kev, fd, filter, EV_ADD|EV_CLEAR, 0, 0, NULL); + if (0 == n) return fd; ts.tv_sec = 0; ts.tv_nsec = 0; ret = kevent(ev->kq_fd, - &kev, 1, + kev, n, NULL, 0, &ts); if (ret == -1) { log_error_write(ev->srv, __FILE__, __LINE__, "SS", - "kqueue event add failed: ", strerror(errno)); + "kqueue event set failed: ", strerror(errno)); return -1; } @@ -161,7 +190,7 @@ int fdevent_freebsd_kqueue_init(fdevents *ev) { SET(reset); SET(event_del); - SET(event_add); + SET(event_set); SET(event_next_fdndx); SET(event_get_fd); |