/*! \brief * Make the poll call, and call * the callbacks for anything that needs * to be handled */ int ast_io_wait(struct io_context *ioc, int howlong) { int res, x, origcnt; DEBUG(ast_debug(1, "ast_io_wait()\n")); if ((res = ast_poll(ioc->fds, ioc->fdcnt, howlong)) <= 0) { return res; } /* At least one event tripped */ origcnt = ioc->fdcnt; for (x = 0; x < origcnt; x++) { /* Yes, it is possible for an entry to be deleted and still have an event waiting if it occurs after the original calling id */ if (ioc->fds[x].revents && ioc->ior[x].id) { /* There's an event waiting */ ioc->current_ioc = *ioc->ior[x].id; if (ioc->ior[x].callback) { if (!ioc->ior[x].callback(ioc->ior[x].id, ioc->fds[x].fd, ioc->fds[x].revents, ioc->ior[x].data)) { /* Time to delete them since they returned a 0 */ ast_io_remove(ioc, ioc->ior[x].id); } } ioc->current_ioc = -1; } } if (ioc->needshrink) io_shrink(ioc); return res; }
static int timed_read(int fd, void *data, int datalen, int timeout, int pid) { int res; int i; struct pollfd fds[1]; fds[0].fd = fd; fds[0].events = POLLIN; for (i = 0; i < timeout; i++) { res = ast_poll(fds, 1, 1000); if (res > 0) { break; } else if (res == 0) { /* is mpg123 still running? */ kill(pid, 0); if (errno == ESRCH) { return -1; } } else { ast_log(LOG_NOTICE, "error polling mpg123: %s\n", strerror(errno)); return -1; } } if (i == timeout) { ast_log(LOG_NOTICE, "Poll timed out.\n"); return -1; } return read(fd, data, datalen); }
/*! * \internal * \pre timer is locked * \retval 0 if nothing to read or read success * \retval -1 on error */ static int read_pipe(struct pthread_timer *timer, unsigned int quantity) { int rd_fd = timer->pipe[PIPE_READ]; int pending_ticks = timer->pending_ticks; ast_assert(quantity); if (timer->continuous && pending_ticks) { pending_ticks--; } if (quantity > pending_ticks) { quantity = pending_ticks; } if (!quantity) { return 0; } do { unsigned char buf[1024]; ssize_t res; struct pollfd pfd = { .fd = rd_fd, .events = POLLIN, }; if (ast_poll(&pfd, 1, 0) != 1) { ast_debug(1, "Reading not available on timing pipe, " "quantity: %u\n", quantity); return -1; } res = read(rd_fd, buf, (quantity < sizeof(buf)) ? quantity : sizeof(buf)); if (res == -1) { if (errno == EAGAIN) { continue; } ast_log(LOG_ERROR, "read failed on timing pipe: %s\n", strerror(errno)); return -1; } quantity -= res; timer->pending_ticks -= res; } while (quantity); return 0; }
static int timed_read(int fd, void *data, int datalen) { int res; struct pollfd fds[1]; fds[0].fd = fd; fds[0].events = POLLIN; res = ast_poll(fds, 1, 2000); if (res < 1) { ast_log(LOG_NOTICE, "Selected timed out/errored out with %d\n", res); return -1; } return read(fd, data, datalen); }
int ooSocketPoll(struct pollfd *pfds, int nfds, int timeout) { return ast_poll(pfds, nfds, timeout); }
static char *timing_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { struct ast_timer *timer; int count = 0; struct timeval start, end; unsigned int test_rate = 50; switch (cmd) { case CLI_INIT: e->command = "timing test"; e->usage = "Usage: timing test <rate>\n" " Test a timer with a specified rate, 50/sec by default.\n" ""; return NULL; case CLI_GENERATE: return NULL; } if (a->argc != 2 && a->argc != 3) { return CLI_SHOWUSAGE; } if (a->argc == 3) { unsigned int rate; if (sscanf(a->argv[2], "%30u", &rate) == 1) { test_rate = rate; } else { ast_cli(a->fd, "Invalid rate '%s', using default of %u\n", a->argv[2], test_rate); } } ast_cli(a->fd, "Attempting to test a timer with %u ticks per second.\n", test_rate); if (!(timer = ast_timer_open())) { ast_cli(a->fd, "Failed to open timing fd\n"); return CLI_FAILURE; } ast_cli(a->fd, "Using the '%s' timing module for this test.\n", timer->holder->iface->name); start = ast_tvnow(); ast_timer_set_rate(timer, test_rate); while (ast_tvdiff_ms((end = ast_tvnow()), start) < 1000) { int res; struct pollfd pfd = { .fd = ast_timer_fd(timer), .events = POLLIN | POLLPRI, }; res = ast_poll(&pfd, 1, 100); if (res == 1) { count++; if (ast_timer_ack(timer, 1) < 0) { ast_cli(a->fd, "Timer failed to acknowledge.\n"); ast_timer_close(timer); return CLI_FAILURE; } } else if (!res) { ast_cli(a->fd, "poll() timed out! This is bad.\n"); } else if (errno != EAGAIN && errno != EINTR) { ast_cli(a->fd, "poll() returned error: %s\n", strerror(errno)); } } ast_timer_close(timer); timer = NULL; ast_cli(a->fd, "It has been %" PRIi64 " milliseconds, and we got %d timer ticks\n", ast_tvdiff_ms(end, start), count); return CLI_SUCCESS; } static struct ast_cli_entry cli_timing[] = { AST_CLI_DEFINE(timing_test, "Run a timing test"), }; static void timing_shutdown(void) { ast_cli_unregister_multiple(cli_timing, ARRAY_LEN(cli_timing)); ast_heap_destroy(timing_interfaces); timing_interfaces = NULL; }