/* called when ares wants to change the event mask */ static void sock_state_cb(void *data, ares_socket_t socket_fd, int readable, int writable) { ph_dns_channel_t *chan = data; ph_job_t *job; ph_iomask_t mask = 0; if (readable) { mask |= PH_IOMASK_READ; } if (writable) { mask |= PH_IOMASK_WRITE; } if (ph_ht_lookup(&chan->sock_map, &socket_fd, &job, false) != PH_OK) { ph_panic("job for socket %d was not found in ares sock_state_cb", socket_fd); } if (mask) { apply_mask(chan, job, mask); } else { ph_job_set_nbio(job, 0, NULL); // We're done with this guy, remove it ph_ht_del(&chan->sock_map, &socket_fd); ph_mem_free(mt.job, job); } }
static void tick_epoll(ph_job_t *job, ph_iomask_t why, void *data) { uint64_t expirations = 0; struct ph_nbio_emitter *emitter = data; ph_unused_parameter(job); ph_unused_parameter(why); ph_unused_parameter(data); /* consume the number of ticks; ideally this is 1; anything bigger * means that we've fallen behind */ if (read(emitter->timer_fd, &expirations, sizeof(expirations)) > 0) { if (expirations) { ph_nbio_emitter_timer_tick(emitter); } } ph_job_set_nbio(job, PH_IOMASK_READ, 0); }
void ph_nbio_emitter_init(struct ph_nbio_emitter *emitter) { struct itimerspec ts; #ifdef HAVE_EPOLL_CREATE1 emitter->io_fd = epoll_create1(EPOLL_CLOEXEC); #else emitter->io_fd = epoll_create(1024*1024); #endif if (emitter->io_fd == -1) { ph_panic("epoll_create: `Pe%d", errno); } #ifndef HAVE_EPOLL_CREATE1 fcntl(emitter->io_fd, F_SETFD, FD_CLOEXEC); #endif emitter->timer_fd = timerfd_create( CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC); if (emitter->timer_fd == -1) { ph_panic("timerfd_create(CLOCK_MONOTONIC) failed: `Pe%d", errno); } memset(&ts, 0, sizeof(ts)); ts.it_interval.tv_nsec = WHEEL_INTERVAL_MS * 1000000; ts.it_value.tv_nsec = ts.it_interval.tv_nsec; timerfd_settime(emitter->timer_fd, 0, &ts, NULL); ph_job_init(&emitter->timer_job); emitter->timer_job.callback = tick_epoll; emitter->timer_job.fd = emitter->timer_fd; emitter->timer_job.data = emitter; emitter->timer_job.emitter_affinity = emitter->emitter_id; ph_job_set_nbio(&emitter->timer_job, PH_IOMASK_READ, 0); }