static void iv_fd_kqueue_poll(struct iv_state *st, struct iv_list_head *active, const struct timespec *abs) { struct kevent kev[UPLOAD_BATCH]; int num; struct kevent batch[st->numfds ? 2 * st->numfds : 1]; struct timespec rel; int ret; int run_events; int i; iv_fd_kqueue_upload(st, kev, UPLOAD_BATCH, &num); ret = kevent(st->u.kqueue.kqueue_fd, kev, num, batch, ARRAY_SIZE(batch), to_relative(st, &rel, abs)); __iv_invalidate_now(st); if (ret < 0) { if (errno == EINTR) return; iv_fatal("iv_fd_kqueue_poll: got error %d[%s]", errno, strerror(errno)); } run_events = 0; for (i = 0; i < ret; i++) { struct iv_fd_ *fd; if (batch[i].filter == EVFILT_USER) { run_events = 1; continue; } if (batch[i].flags & EV_ERROR) { int err = batch[i].data; int fd = batch[i].ident; iv_fatal("iv_fd_kqueue_poll: got error %d[%s] " "polling fd %d", err, strerror(err), fd); } fd = (void *)batch[i].udata; if (batch[i].filter == EVFILT_READ) { iv_fd_make_ready(active, fd, MASKIN); } else if (batch[i].filter == EVFILT_WRITE) { iv_fd_make_ready(active, fd, MASKOUT); } else { iv_fatal("iv_fd_kqueue_poll: got message from " "filter %d", batch[i].filter); } } if (run_events) iv_event_run_pending_events(); }
static int iv_fd_port_poll(struct iv_state *st, struct iv_list_head *active, const struct timespec *abs) { struct timespec _rel; struct timespec *rel; int run_timers; int run_events; unsigned int nget; port_event_t pe[PORTEV_NUM]; int ret; int i; iv_fd_port_upload(st); rel = to_relative(st, &_rel, abs); run_timers = 0; if (rel != NULL && rel->tv_sec == 0 && rel->tv_nsec == 0) run_timers = 1; run_events = 0; poll_more: nget = 1; /* * If we get EINTR from port_getn(), no events are returned * and nget will not have been updated, but if we get ETIME, * events may be returned, and nget will be set to the number * of events in the array, and we need to process those * events as usual. */ ret = port_getn(st->u.port.port_fd, pe, PORTEV_NUM, &nget, rel); __iv_invalidate_now(st); if (ret < 0 && errno != ETIME) { if (errno == EINTR) return run_timers; iv_fatal("iv_fd_port_poll: got error %d[%s]", errno, strerror(errno)); } if (ret < 0 && errno == ETIME) run_timers = 1; for (i = 0; i < nget; i++) { int source; source = pe[i].portev_source; if (source == PORT_SOURCE_FD) { int revents; struct iv_fd_ *fd; revents = pe[i].portev_events; fd = pe[i].portev_user; if (revents & (POLLIN | POLLERR | POLLHUP)) iv_fd_make_ready(active, fd, MASKIN); if (revents & (POLLOUT | POLLERR | POLLHUP)) iv_fd_make_ready(active, fd, MASKOUT); if (revents & (POLLERR | POLLHUP)) iv_fd_make_ready(active, fd, MASKERR); fd->registered_bands = 0; iv_list_del_init(&fd->list_notify); if (fd->wanted_bands) { iv_list_add_tail(&fd->list_notify, &st->u.port.notify); } } else if (source == PORT_SOURCE_TIMER) { run_timers = 1; } else if (source == PORT_SOURCE_USER) { run_events = 1; } else { iv_fatal("iv_fd_port_poll: received event " "from unknown source %d", source); } } if (nget == PORTEV_NUM) { run_timers = 1; rel = &_rel; rel->tv_sec = 0; rel->tv_nsec = 0; goto poll_more; } if (run_events) iv_event_run_pending_events(); return run_timers; }