kqueue(void) { struct kqueue *kq; int tmp; kq = calloc(1, sizeof(*kq)); if (kq == NULL) return (-1); kq->kq_ref = 1; pthread_mutex_init(&kq->kq_mtx, NULL); #ifdef NDEBUG KQUEUE_DEBUG = 0; #else KQUEUE_DEBUG = (getenv("KQUEUE_DEBUG") == NULL) ? 0 : 1; #endif if (socketpair(AF_UNIX, SOCK_STREAM, 0, kq->kq_sockfd) < 0) goto errout_unlocked; if (kqueue_sys_init(kq) < 0) goto errout_unlocked; pthread_rwlock_wrlock(&kqtree_mtx); if (kqueue_gc() < 0) goto errout; /* TODO: move outside of the lock if it is safe */ if (filter_register_all(kq) < 0) goto errout; RB_INSERT(kqt, &kqtree, kq); pthread_rwlock_unlock(&kqtree_mtx); dbg_printf("created kqueue, fd=%d", kq->kq_sockfd[1]); return (kq->kq_sockfd[1]); errout: pthread_rwlock_unlock(&kqtree_mtx); errout_unlocked: if (kq->kq_sockfd[0] != kq->kq_sockfd[1]) { tmp = errno; (void)close(kq->kq_sockfd[0]); (void)close(kq->kq_sockfd[1]); errno = tmp; } #if defined(__sun__) if (kq->kq_port > 0) close(kq->kq_port); #endif free(kq); return (-1); }
int linux_kqueue_init(struct kqueue *kq) { kq->kq_id = epoll_create(1); if (kq->kq_id < 0) { dbg_perror("epoll_create(2)"); return (-1); } if (filter_register_all(kq) < 0) { close(kq->kq_id); return (-1); } #if DEADWOOD //might be useful in posix /* Add each filter's pollable descriptor to the epollset */ for (i = 0; i < EVFILT_SYSCOUNT; i++) { filt = &kq->kq_filt[i]; if (filt->kf_id == 0) continue; memset(&ev, 0, sizeof(ev)); ev.events = EPOLLIN; ev.data.ptr = filt; if (epoll_ctl(kq->kq_id, EPOLL_CTL_ADD, filt->kf_pfd, &ev) < 0) { dbg_perror("epoll_ctl(2)"); close(kq->kq_id); return (-1); } } #endif return (0); }