int sel_stop_timer(sel_timer_t *timer) { if (!timer->in_heap) return ETIMEDOUT; remove_from_heap(&(timer->sel->timer_top), &(timer->sel->timer_last), timer); timer->in_heap = 0; return 0; }
int sel_start_timer(sel_timer_t *timer, struct timeval *timeout) { if (timer->in_heap) remove_from_heap(&(timer->sel->timer_top), &(timer->sel->timer_last), timer); timer->timeout = *timeout; add_to_heap(&(timer->sel->timer_top), &(timer->sel->timer_last), timer); timer->in_heap = 1; return 0; }
void sel_select_once(selector_t *sel) { fd_set tmp_read_set; fd_set tmp_write_set; fd_set tmp_except_set; int i; int err; sel_timer_t *timer; struct timeval timeout, *to_time; if (sel->timer_top) { struct timeval now; /* Check for timers to time out. */ gettimeofday(&now, NULL); timer = sel->timer_top; while (cmp_timeval(&now, &timer->timeout) >= 0) { remove_from_heap(&(sel->timer_top), &(sel->timer_last), timer); timer->in_heap = 0; timer->handler(sel, timer, timer->user_data); timer = sel->timer_top; gettimeofday(&now, NULL); if (!timer) goto no_timers; } /* Calculate how long to wait now. */ diff_timeval(&timeout, &sel->timer_top->timeout, &now); to_time = &timeout; } else { no_timers: to_time = NULL; } memcpy(&tmp_read_set, &sel->read_set, sizeof(tmp_read_set)); memcpy(&tmp_write_set, &sel->write_set, sizeof(tmp_write_set)); memcpy(&tmp_except_set, &sel->except_set, sizeof(tmp_except_set)); err = select(sel->maxfd+1, &tmp_read_set, &tmp_write_set, &tmp_except_set, to_time); if (err == 0) { /* A timeout occurred. */ } else if (err < 0) { /* An error occurred. */ if (errno == EINTR) { /* EINTR is ok, just restart the operation. */ timeout.tv_sec = 1; timeout.tv_usec = 0; } else { /* An error is bad, we need to abort. */ syslog(LOG_ERR, "select_loop() - select: %m"); exit(1); } } else { /* We got some I/O. */ for (i=0; i<=sel->maxfd; i++) { if (FD_ISSET(i, &tmp_read_set)) { if (sel->fds[i].handle_read == NULL) { /* Somehow we don't have a handler for this. Just shut it down. */ sel_set_fd_read_handler(sel, i, SEL_FD_HANDLER_DISABLED); } else { sel->fds[i].handle_read(i, sel->fds[i].data); } } if (FD_ISSET(i, &tmp_write_set)) { if (sel->fds[i].handle_write == NULL) { /* Somehow we don't have a handler for this. Just shut it down. */ sel_set_fd_write_handler(sel, i, SEL_FD_HANDLER_DISABLED); } else { sel->fds[i].handle_write(i, sel->fds[i].data); } } if (FD_ISSET(i, &tmp_except_set)) { if (sel->fds[i].handle_except == NULL) { /* Somehow we don't have a handler for this. Just shut it down. */ sel_set_fd_except_handler(sel, i, SEL_FD_HANDLER_DISABLED); } else { sel->fds[i].handle_except(i, sel->fds[i].data); } } } } if (got_sighup) { got_sighup = 0; if (user_sighup_handler != NULL) { user_sighup_handler(); } } if (got_sigint) { got_sigint = 0; if (user_sigint_handler != NULL) { user_sigint_handler(); } } }
static void remove_from_heap(const RandomAccessIterator &first, const RandomAccessIterator &item, const RandomAccessIterator &last) { remove_from_heap(first, item, last, _std_less_comparer<RandomAccessIterator>); }