diff options
author | Felix Fietkau <nbd@nbd.name> | 2016-05-17 13:24:04 +0300 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2016-05-17 14:23:38 +0300 |
commit | 4b0aa9ccc22eff62e177b9777152e7937273b418 (patch) | |
tree | 33848f2c010005e256a68cb914b265e850d3b416 /uloop.c | |
parent | 155bf39896f126b1ba121b816922a88dc34c31e3 (diff) |
uloop: move kqueue code into a separate file
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'uloop.c')
-rw-r--r-- | uloop.c | 136 |
1 files changed, 2 insertions, 134 deletions
@@ -1,7 +1,7 @@ /* * uloop - event loop implementation * - * Copyright (C) 2010-2013 Felix Fietkau <nbd@openwrt.org> + * Copyright (C) 2010-2016 Felix Fietkau <nbd@openwrt.org> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -64,139 +64,7 @@ static struct uloop_fd_event cur_fds[ULOOP_MAX_EVENTS]; static int cur_fd, cur_nfds; #ifdef USE_KQUEUE - -int uloop_init(void) -{ - struct timespec timeout = { 0, 0 }; - struct kevent ev = {}; - - if (poll_fd >= 0) - return 0; - - poll_fd = kqueue(); - if (poll_fd < 0) - return -1; - - EV_SET(&ev, SIGCHLD, EVFILT_SIGNAL, EV_ADD, 0, 0, 0); - kevent(poll_fd, &ev, 1, NULL, 0, &timeout); - - return 0; -} - - -static uint16_t get_flags(unsigned int flags, unsigned int mask) -{ - uint16_t kflags = 0; - - if (!(flags & mask)) - return EV_DELETE; - - kflags = EV_ADD; - if (flags & ULOOP_EDGE_TRIGGER) - kflags |= EV_CLEAR; - - return kflags; -} - -static struct kevent events[ULOOP_MAX_EVENTS]; - -static int register_kevent(struct uloop_fd *fd, unsigned int flags) -{ - struct timespec timeout = { 0, 0 }; - struct kevent ev[2]; - int nev = 0; - unsigned int fl = 0; - unsigned int changed; - uint16_t kflags; - - if (flags & ULOOP_EDGE_DEFER) - flags &= ~ULOOP_EDGE_TRIGGER; - - changed = flags ^ fd->flags; - if (changed & ULOOP_EDGE_TRIGGER) - changed |= flags; - - if (changed & ULOOP_READ) { - kflags = get_flags(flags, ULOOP_READ); - EV_SET(&ev[nev++], fd->fd, EVFILT_READ, kflags, 0, 0, fd); - } - - if (changed & ULOOP_WRITE) { - kflags = get_flags(flags, ULOOP_WRITE); - EV_SET(&ev[nev++], fd->fd, EVFILT_WRITE, kflags, 0, 0, fd); - } - - if (!flags) - fl |= EV_DELETE; - - fd->flags = flags; - if (kevent(poll_fd, ev, nev, NULL, fl, &timeout) == -1) - return -1; - - return 0; -} - -static int register_poll(struct uloop_fd *fd, unsigned int flags) -{ - if (flags & ULOOP_EDGE_TRIGGER) - flags |= ULOOP_EDGE_DEFER; - else - flags &= ~ULOOP_EDGE_DEFER; - - return register_kevent(fd, flags); -} - -static int __uloop_fd_delete(struct uloop_fd *fd) -{ - return register_poll(fd, 0); -} - -static int uloop_fetch_events(int timeout) -{ - struct timespec ts; - int nfds, n; - - if (timeout >= 0) { - ts.tv_sec = timeout / 1000; - ts.tv_nsec = (timeout % 1000) * 1000000; - } - - nfds = kevent(poll_fd, NULL, 0, events, ARRAY_SIZE(events), timeout >= 0 ? &ts : NULL); - for (n = 0; n < nfds; n++) { - struct uloop_fd_event *cur = &cur_fds[n]; - struct uloop_fd *u = events[n].udata; - unsigned int ev = 0; - - cur->fd = u; - if (!u) - continue; - - if (events[n].flags & EV_ERROR) { - u->error = true; - if (!(u->flags & ULOOP_ERROR_CB)) - uloop_fd_delete(u); - } - - if(events[n].filter == EVFILT_READ) - ev |= ULOOP_READ; - else if (events[n].filter == EVFILT_WRITE) - ev |= ULOOP_WRITE; - - if (events[n].flags & EV_EOF) - u->eof = true; - else if (!ev) - cur->fd = NULL; - - cur->events = ev; - if (u->flags & ULOOP_EDGE_DEFER) { - u->flags &= ~ULOOP_EDGE_DEFER; - u->flags |= ULOOP_EDGE_TRIGGER; - register_kevent(u, u->flags); - } - } - return nfds; -} - +#include "uloop-kqueue.c" #endif #ifdef USE_EPOLL |