/* * comm_setselect * * This is a needed exported function which will be called to register * and deregister interest in a pending IO state for a given FD. */ void comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler, void *client_data, time_t timeout) { fde_t *F = &fd_table[fd]; assert(fd >= 0); assert(F->flags.open); /* Update the list, even though we're not using it .. */ F->list = list; if (type & COMM_SELECT_READ) { kq_update_events(fd, EVFILT_READ, handler); F->read_handler = handler; F->read_data = client_data; } if (type & COMM_SELECT_WRITE) { kq_update_events(fd, EVFILT_WRITE, handler); F->write_handler = handler; F->write_data = client_data; } if (timeout) F->timeout = CurrentTime + (timeout / 1000); }
/* * rb_setselect * * This is a needed exported function which will be called to register * and deregister interest in a pending IO state for a given FD. */ void rb_setselect_kqueue(rb_fde_t *F, unsigned int type, PF * handler, void *client_data) { lrb_assert(IsFDOpen(F)); if(type & RB_SELECT_READ) { kq_update_events(F, EVFILT_READ, handler); F->read_handler = handler; F->read_data = client_data; } if(type & RB_SELECT_WRITE) { kq_update_events(F, EVFILT_WRITE, handler); F->write_handler = handler; F->write_data = client_data; } }
/* * comm_setselect * * This is a needed exported function which will be called to register * and deregister interest in a pending IO state for a given FD. */ void comm_setselect(fde_t *F, unsigned int type, void (*handler)(fde_t *, void *), void *client_data, time_t timeout) { int new_events, diff; if ((type & COMM_SELECT_READ)) { F->read_handler = handler; F->read_data = client_data; } if ((type & COMM_SELECT_WRITE)) { F->write_handler = handler; F->write_data = client_data; } new_events = (F->read_handler ? COMM_SELECT_READ : 0) | (F->write_handler ? COMM_SELECT_WRITE : 0); if (timeout != 0) { F->timeout = CurrentTime + (timeout / 1000); F->timeout_handler = handler; F->timeout_data = client_data; } diff = new_events ^ F->evcache; if ((diff & COMM_SELECT_READ)) kq_update_events(F->fd, EVFILT_READ, (new_events & COMM_SELECT_READ) ? EV_ADD : EV_DELETE); if ((diff & COMM_SELECT_WRITE)) kq_update_events(F->fd, EVFILT_WRITE, (new_events & COMM_SELECT_WRITE) ? EV_ADD : EV_DELETE); F->evcache = new_events; }
/* * Write a single update to the kqueue list. */ static void kq_update_events(int fd, int filter, int what) { const struct timespec zero_timespec = { .tv_sec = 0, .tv_nsec = 0 }; struct kevent *kep = kq_fdlist + kqoff; EV_SET(kep, (uintptr_t) fd, (short) filter, what, 0, 0, NULL); if (++kqoff == KE_LENGTH) { int i; for (i = 0; i < kqoff; ++i) kevent(kqfd.fd, &kq_fdlist[i], 1, NULL, 0, &zero_timespec); kqoff = 0; } } /* * comm_setselect * * This is a needed exported function which will be called to register * and deregister interest in a pending IO state for a given FD. */ void comm_setselect(fde_t *F, unsigned int type, void (*handler)(fde_t *, void *), void *client_data, uintmax_t timeout) { int new_events, diff; if ((type & COMM_SELECT_READ)) { F->read_handler = handler; F->read_data = client_data; } if ((type & COMM_SELECT_WRITE)) { F->write_handler = handler; F->write_data = client_data; } new_events = (F->read_handler ? COMM_SELECT_READ : 0) | (F->write_handler ? COMM_SELECT_WRITE : 0); if (timeout != 0) { F->timeout = CurrentTime + (timeout / 1000); F->timeout_handler = handler; F->timeout_data = client_data; } diff = new_events ^ F->evcache; if ((diff & COMM_SELECT_READ)) kq_update_events(F->fd, EVFILT_READ, (new_events & COMM_SELECT_READ) ? EV_ADD : EV_DELETE); if ((diff & COMM_SELECT_WRITE)) kq_update_events(F->fd, EVFILT_WRITE, (new_events & COMM_SELECT_WRITE) ? EV_ADD : EV_DELETE); F->evcache = new_events; }