static int init_pollset(struct cfg *cf, struct rtpp_cmd_pollset *psp) { struct rtpp_ctrl_sock *ctrl_sock; int pfds_used, msize, i; pfds_used = 0; ctrl_sock = RTPP_LIST_HEAD(cf->stable->ctrl_socks); for (pfds_used = 0; ctrl_sock != NULL; ctrl_sock = RTPP_ITER_NEXT(ctrl_sock)) { if (RTPP_CTRL_ISUNIX(ctrl_sock)) continue; pfds_used++; } msize = pfds_used > 0 ? pfds_used : 1; psp->pfds = malloc(sizeof(struct pollfd) * msize); if (psp->pfds == NULL) { return (-1); } if (pthread_mutex_init(&psp->pfds_mutex, NULL) != 0) { free(psp->pfds); return (-1); } psp->pfds_used = pfds_used; if (psp->pfds_used == 0) { return (0); } ctrl_sock = RTPP_LIST_HEAD(cf->stable->ctrl_socks); for (i = 0; ctrl_sock != NULL; ctrl_sock = RTPP_ITER_NEXT(ctrl_sock)) { if (RTPP_CTRL_ISUNIX(ctrl_sock)) continue; psp->pfds[i].fd = ctrl_sock->controlfd_in; psp->pfds[i].events = POLLIN; psp->pfds[i].revents = 0; psp->rccs[i] = rtpp_cmd_connection_ctor(ctrl_sock->controlfd_in, ctrl_sock->controlfd_out, ctrl_sock); i++; } if (i == 1 && RTPP_CTRL_ISSTREAM(psp->rccs[0]->csock)) { psp->rccs[0]->csock->exit_on_close = 1; } return (0); }
void rtpp_controlfd_cleanup(struct cfg *cf) { struct rtpp_ctrl_sock *ctrl_sock; for (ctrl_sock = RTPP_LIST_HEAD(cf->stable->ctrl_socks); ctrl_sock != NULL; ctrl_sock = RTPP_ITER_NEXT(ctrl_sock)) { if (RTPP_CTRL_ISUNIX(ctrl_sock) == 0) continue; unlink(ctrl_sock->cmd_sock); } }
static int init_accptset(struct cfg *cf, struct rtpp_cmd_accptset *asp) { int i, pfds_used; struct rtpp_ctrl_sock *ctrl_sock; pfds_used = 0; ctrl_sock = RTPP_LIST_HEAD(cf->stable->ctrl_socks); for (pfds_used = 0; ctrl_sock != NULL; ctrl_sock = RTPP_ITER_NEXT(ctrl_sock)) { if (RTPP_CTRL_ISUNIX(ctrl_sock) == 0) continue; pfds_used++; } if (pfds_used == 0) { return (0); } asp->pfds = malloc(sizeof(struct pollfd) * pfds_used); if (asp->pfds == NULL) { return (-1); } asp->pfds_used = pfds_used; asp->csocks = malloc(sizeof(struct rtpp_ctrl_sock) * pfds_used); if (asp->csocks == NULL) { free(asp->pfds); return (-1); } ctrl_sock = RTPP_LIST_HEAD(cf->stable->ctrl_socks); for (i = 0; i < asp->pfds_used; ctrl_sock = RTPP_ITER_NEXT(ctrl_sock)) { if (RTPP_CTRL_ISUNIX(ctrl_sock) == 0) continue; asp->pfds[i].fd = ctrl_sock->controlfd_in; asp->pfds[i].events = POLLIN; asp->pfds[i].revents = 0; asp->csocks[i] = ctrl_sock; i++; } return (pfds_used); }
static struct rtpp_cmd_connection * rtpp_cmd_connection_ctor(int controlfd_in, int controlfd_out, struct rtpp_ctrl_sock *csock, struct sockaddr *rap) { struct rtpp_cmd_connection *rcc; rcc = malloc(sizeof(struct rtpp_cmd_connection)); if (rcc == NULL) { return (NULL); } memset(rcc, '\0', sizeof(struct rtpp_cmd_connection)); rcc->controlfd_in = controlfd_in; rcc->controlfd_out = controlfd_out; rcc->csock = csock; if (rap != NULL && RTPP_CTRL_ISUNIX(csock) == 0) { rcc->rlen = SA_LEN(rap); memcpy(&rcc->raddr, rap, rcc->rlen); } return (rcc); }
static void rtpp_cmd_queue_run(void *arg) { struct rtpp_cmd_async_cf *cmd_cf; struct rtpp_cmd_pollset *psp; int i, nready, rval, umode; double sptime; #if 0 double eptime, tused; #endif struct rtpp_command_stats *csp; struct rtpp_stats_obj *rtpp_stats_cf; cmd_cf = (struct rtpp_cmd_async_cf *)arg; rtpp_stats_cf = cmd_cf->cf_save->stable->rtpp_stats; csp = &cmd_cf->cstats; psp = &cmd_cf->pset; for (;;) { sptime = getdtime(); pthread_mutex_lock(&psp->pfds_mutex); if (psp->pfds_used == 0) { pthread_mutex_unlock(&psp->pfds_mutex); if (wait_next_clock(cmd_cf) == TSTATE_CEASE) { break; } continue; } nready = poll(psp->pfds, psp->pfds_used, 2); if (nready == 0) { pthread_mutex_unlock(&psp->pfds_mutex); if (wait_next_clock(cmd_cf) == TSTATE_CEASE) { break; } continue; } if (nready < 0 && errno == EINTR) { pthread_mutex_unlock(&psp->pfds_mutex); continue; } if (nready > 0) { for (i = 0; i < psp->pfds_used; i++) { if ((psp->pfds[i].revents & (POLLERR | POLLHUP)) != 0) { if (RTPP_CTRL_ISUNIX(psp->rccs[i]->csock)) { goto closefd; } if (psp->rccs[i]->csock->type == RTPC_STDIO && (psp->pfds[i].revents & POLLIN) == 0) { goto closefd; } } if ((psp->pfds[i].revents & POLLIN) == 0) { continue; } if (RTPP_CTRL_ISSTREAM(psp->rccs[i]->csock)) { rval = process_commands_stream(cmd_cf->cf_save, psp->rccs[i], sptime, csp, rtpp_stats_cf); } else { umode = RTPP_CTRL_ISDG(psp->rccs[i]->csock); rval = process_commands(cmd_cf->cf_save, psp->pfds[i].fd, sptime, csp, umode, rtpp_stats_cf, cmd_cf->rcache); } /* * Shut down non-datagram sockets that got I/O error * and also all non-continuous UNIX sockets are recycled * after each use. */ if (!RTPP_CTRL_ISDG(psp->rccs[i]->csock) && (rval == -1 || !RTPP_CTRL_ISSTREAM(psp->rccs[i]->csock))) { closefd: if (psp->rccs[i]->csock->type == RTPC_STDIO && psp->rccs[i]->csock->exit_on_close != 0) { cmd_cf->cf_save->stable->slowshutdown = 1; } rtpp_cmd_connection_dtor(psp->rccs[i]); psp->pfds_used--; if (psp->pfds_used > 0 && i < psp->pfds_used) { memcpy(&psp->pfds[i], &psp->pfds[i + 1], (psp->pfds_used - i) * sizeof(struct pollfd)); memcpy(&psp->rccs[i], &psp->rccs[i + 1], (psp->pfds_used - i) * sizeof(struct rtpp_ctrl_connection *)); } } } } pthread_mutex_unlock(&psp->pfds_mutex); if (nready > 0) { rtpp_anetio_pump(cmd_cf->cf_save->stable->rtpp_netio_cf); } #if 0 eptime = getdtime(); pthread_mutex_lock(&cmd_cf->cmd_mutex); recfilter_apply(&cmd_cf->average_load, (eptime - sptime + tused) * cmd_cf->cf_save->stable->target_pfreq); pthread_mutex_unlock(&cmd_cf->cmd_mutex); #endif flush_cstats(rtpp_stats_cf, csp); #if 0 #if RTPP_DEBUG if (last_ctick % (unsigned int)cmd_cf->cf_save->stable->target_pfreq == 0 || last_ctick < 1000) { rtpp_log_write(RTPP_LOG_DBUG, cmd_cf->cf_save->stable->glog, "rtpp_cmd_queue_run %lld sptime %f eptime %f, CSV: %f,%f,%f,%f,%f", \ last_ctick, sptime, eptime, (double)last_ctick / cmd_cf->cf_save->stable->target_pfreq, \ eptime - sptime + tused, eptime, sptime, tused); rtpp_log_write(RTPP_LOG_DBUG, cmd_cf->cf_save->stable->glog, "run %lld average load %f, CSV: %f,%f", last_ctick, \ cmd_cf->average_load.lastval * 100.0, (double)last_ctick / cmd_cf->cf_save->stable->target_pfreq, cmd_cf->average_load.lastval); } #endif #endif } }