コード例 #1
0
int
rtpp_proc_async_init(struct cfg *cf)
{
    struct rtpp_proc_async_cf *proc_cf;

    proc_cf = malloc(sizeof(*proc_cf));
    if (proc_cf == NULL)
        return (-1);

    memset(proc_cf, '\0', sizeof(*proc_cf));

    init_rstats(cf->stable->rtpp_stats, &proc_cf->rstats);

#if RTPP_DEBUG
    recfilter_init(&proc_cf->sleep_time, 0.999, 0.0, 0);
    recfilter_init(&proc_cf->poll_time, 0.999, 0.0, 0);
    recfilter_init(&proc_cf->proc_time, 0.999, 0.0, 0);
#endif

    proc_cf->time_q = rtpp_queue_init(1, "RTP_PROC(time)");
    if (proc_cf->time_q == NULL) {
        free(proc_cf);
        return (-1);
    }

    proc_cf->op = rtpp_netio_async_init(cf, 10);
    if (proc_cf->op == NULL) {
        rtpp_queue_destroy(proc_cf->time_q);
        free(proc_cf);
        return (-1);
    }

    cf->stable->rtpp_proc_cf = proc_cf;
    if (pthread_create(&proc_cf->thread_id, NULL, (void *(*)(void *))&rtpp_proc_async_run, cf) != 0) {
        rtpp_queue_destroy(proc_cf->time_q);
        rtpp_netio_async_destroy(proc_cf->op);
        free(proc_cf);
        cf->stable->rtpp_proc_cf = NULL;
        return (-1);
    }

    return (0);
}
コード例 #2
0
ファイル: main.c プロジェクト: bjhockley/rtpproxy
int
main(int argc, char **argv)
{
    int i, len, controlfd;
    double eval, clk;
    long long ncycles_ref, counter;
    double eptime;
    double add_delay;
    struct cfg cf;
    char buf[256];
    struct recfilter loop_error;
    struct PFD phase_detector;
    useconds_t usleep_time;
    struct sched_param sparam;
#if RTPP_DEBUG
    double sleep_time, filter_lastval;
#endif
    memset(&cf, 0, sizeof(cf));

    cf.stable = malloc(sizeof(struct rtpp_cfg_stable));
    if (cf.stable == NULL) {
         err(1, "can't allocate memory for the struct rtpp_cfg_stable");
         /* NOTREACHED */
    }
    memset(cf.stable, '\0', sizeof(struct rtpp_cfg_stable));

    init_config(&cf, argc, argv);

    seedrandom();

    cf.stable->sessions_ht = rtpp_hash_table_ctor();
    if (cf.stable->sessions_ht == NULL) {
        err(1, "can't allocate memory for the hash table");
         /* NOTREACHED */
    }
    cf.stable->rtpp_stats = rtpp_stats_ctor();
    if (cf.stable->rtpp_stats == NULL) {
        err(1, "can't allocate memory for the stats data");
         /* NOTREACHED */
    }
    init_port_table(&cf);

    controlfd = init_controlfd(&cf);

    if (cf.stable->nodaemon == 0) {
	if (rtpp_daemon(0, 0) == -1)
	    err(1, "can't switch into daemon mode");
	    /* NOTREACHED */
    }

    if (rtpp_notify_init() != 0)
        errx(1, "can't start notification thread");

    cf.stable->glog = rtpp_log_open(cf.stable, "rtpproxy", NULL, LF_REOPEN);
    rtpp_log_setlevel(cf.stable->glog, cf.stable->log_level);
    _sig_cf = &cf;
    atexit(ehandler);
    rtpp_log_write(RTPP_LOG_INFO, cf.stable->glog, "rtpproxy started, pid %d", getpid());

    i = open(pid_file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE);
    if (i >= 0) {
	len = sprintf(buf, "%u\n", (unsigned int)getpid());
	write(i, buf, len);
	close(i);
    } else {
	rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog, "can't open pidfile for writing");
    }

    signal(SIGHUP, sighup);
    signal(SIGINT, fatsignal);
    signal(SIGKILL, fatsignal);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGTERM, fatsignal);
    signal(SIGXCPU, fatsignal);
    signal(SIGXFSZ, fatsignal);
    signal(SIGVTALRM, fatsignal);
    signal(SIGPROF, fatsignal);
    signal(SIGUSR1, fatsignal);
    signal(SIGUSR2, fatsignal);

    if (cf.stable->sched_policy != SCHED_OTHER) {
        sparam.sched_priority = sched_get_priority_max(cf.stable->sched_policy);
        if (sched_setscheduler(0, cf.stable->sched_policy, &sparam) == -1) {
            rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog, "sched_setscheduler(SCHED_%s, %d)",
              (cf.stable->sched_policy == SCHED_FIFO) ? "FIFO" : "RR", sparam.sched_priority);
        }
    }

    if (cf.stable->run_uname != NULL || cf.stable->run_gname != NULL) {
	if (drop_privileges(&cf) != 0) {
	    rtpp_log_ewrite(RTPP_LOG_ERR, cf.stable->glog,
	      "can't switch to requested user/group");
	    exit(1);
	}
    }
    set_rlimits(&cf);

    cf.stable->controlfd = controlfd;

    cf.sessinfo.sessions[0] = NULL;
    cf.sessinfo.nsessions = 0;
    cf.rtp_nsessions = 0;

    rtpp_command_async_init(&cf);
    rtpp_proc_async_init(&cf);

    counter = 0;
    recfilter_init(&loop_error, 0.96, 0.0, 0);
    PFD_init(&phase_detector, 2.0);
    for (;;) {
	eptime = getdtime();

        clk = (eptime + cf.stable->sched_offset) * cf.stable->target_pfreq;

        ncycles_ref = llrint(clk);

        eval = PFD_get_error(&phase_detector, clk);

#if RTPP_DEBUG
        filter_lastval = loop_error.lastval;
#endif

        if (eval != 0.0) {
            recfilter_apply(&loop_error, sigmoid(eval));
        }

#if RTPP_DEBUG
        if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000) {
          rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld ncycles %f raw error1 %f, filter lastval %f, filter nextval %f",
            counter, clk, eval, filter_lastval, loop_error.lastval);
        }
#endif
        add_delay = freqoff_to_period(cf.stable->target_pfreq, 1.0, loop_error.lastval);
        usleep_time = add_delay * 1000000.0;
#if RTPP_DEBUG
        if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000) {
            rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld filter lastval %f, filter nextval %f, error %f",
              counter, filter_lastval, loop_error.lastval, sigmoid(eval));
            rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld extra sleeping time %llu", counter, usleep_time);
        }
        sleep_time = getdtime();
#endif
        rtpp_proc_async_wakeup(cf.stable->rtpp_proc_cf, counter, ncycles_ref);
        usleep(usleep_time);
#if RTPP_DEBUG
        sleep_time = getdtime() - sleep_time;
        if (counter % (unsigned int)cf.stable->target_pfreq == 0 || counter < 1000 || sleep_time > add_delay * 2.0) {
            rtpp_log_write(RTPP_LOG_DBUG, cf.stable->glog, "run %lld sleeping time required %llu sleeping time actual %f, CSV: %f,%f,%f", \
              counter, usleep_time, sleep_time, (double)counter / cf.stable->target_pfreq, ((double)usleep_time) / 1000.0, sleep_time * 1000.0);
        }
#endif
        counter += 1;
        if (cf.stable->slowshutdown != 0) {
            pthread_mutex_lock(&cf.sessinfo.lock);
            if (cf.sessinfo.nsessions == 0) {
                /* The below unlock is not necessary, but does not hurt either */
                pthread_mutex_unlock(&cf.sessinfo.lock);
                rtpp_log_write(RTPP_LOG_INFO, cf.stable->glog,
                  "deorbiting-burn sequence completed, exiting");
                break;
            }
            pthread_mutex_unlock(&cf.sessinfo.lock);
        }
    }

    exit(0);
}
コード例 #3
0
struct rtpp_cmd_async_obj *
rtpp_command_async_ctor(struct cfg *cf)
{
    struct rtpp_cmd_async_cf *cmd_cf;
    int need_acptr, i;

    cmd_cf = malloc(sizeof(*cmd_cf));
    if (cmd_cf == NULL)
        goto e0;

    memset(cmd_cf, '\0', sizeof(*cmd_cf));

    if (init_pollset(cf, &cmd_cf->pset) == -1) {
        goto e1;
    }
    need_acptr = init_accptset(cf, &cmd_cf->aset);
    if (need_acptr == -1) {
        goto e2;
    }

    init_cstats(cf->stable->rtpp_stats, &cmd_cf->cstats);

    if (pthread_cond_init(&cmd_cf->cmd_cond, NULL) != 0) {
        goto e3;
    }
    if (pthread_mutex_init(&cmd_cf->cmd_mutex, NULL) != 0) {
        goto e4;
    }
    assert(cf->stable->rtpp_timed_cf != NULL);
    cmd_cf->rcache = rtpp_cmd_rcache_ctor(cf->stable->rtpp_timed_cf, 30.0);
    if (cmd_cf->rcache == NULL) {
        goto e5;
    }

#if 0
    recfilter_init(&cmd_cf->average_load, 0.999, 0.0, 1);
#endif

    cmd_cf->cf_save = cf;
    if (need_acptr != 0) {
        if (pthread_create(&cmd_cf->acpt_thread_id, NULL,
          (void *(*)(void *))&rtpp_cmd_acceptor_run, cmd_cf) != 0) {
            goto e6;
        }
        cmd_cf->acceptor_started = 1;
    }
    if (pthread_create(&cmd_cf->thread_id, NULL,
      (void *(*)(void *))&rtpp_cmd_queue_run, cmd_cf) != 0) {
        goto e7;
    }
    cmd_cf->pub.dtor = &rtpp_command_async_dtor;
    cmd_cf->pub.wakeup = &rtpp_command_async_wakeup;
    cmd_cf->pub.get_aload = &rtpp_command_async_get_aload;
    return (&cmd_cf->pub);

e7:
    if (cmd_cf->acceptor_started != 0) {
        for (i = 0; i < cmd_cf->aset.pfds_used; i ++) {
            close(cmd_cf->aset.pfds[i].fd);
        }
        pthread_join(cmd_cf->acpt_thread_id, NULL);
    }
e6:
    CALL_METHOD(cmd_cf->rcache, dtor);
e5:
    pthread_mutex_destroy(&cmd_cf->cmd_mutex);
e4:
    pthread_cond_destroy(&cmd_cf->cmd_cond);
e3:
    free_accptset(&cmd_cf->aset);
e2:
    free_pollset(&cmd_cf->pset);
e1:
    free(cmd_cf);
e0:
    return (NULL);
}
コード例 #4
0
struct rtpp_anetio_cf *
rtpp_netio_async_init(struct cfg *cf, int qlen)
{
    struct rtpp_anetio_cf *netio_cf;
    int i, ri;

    netio_cf = rtpp_zmalloc(sizeof(*netio_cf));
    if (netio_cf == NULL)
        return (NULL);

    for (i = 0; i < SEND_THREADS; i++) {
        netio_cf->args[i].out_q = rtpp_queue_init(qlen, "RTPP->NET%.2d", i);
        if (netio_cf->args[i].out_q == NULL) {
            for (ri = i - 1; ri >= 0; ri--) {
                rtpp_queue_destroy(netio_cf->args[ri].out_q);
            }
            goto e0;
        }
        netio_cf->args[i].glog = cf->stable->glog;
        netio_cf->args[i].dmode = cf->stable->dmode;
#ifdef RTPP_DEBUG
        recfilter_init(&netio_cf->args[i].average_load, 0.9, 0.0, 0);
#endif
    }

    for (i = 0; i < SEND_THREADS; i++) {
        netio_cf->args[i].sigterm = rtpp_wi_malloc_sgnl(SIGTERM, NULL, 0);
        if (netio_cf->args[i].sigterm == NULL) {
            for (ri = i - 1; ri >= 0; ri--) {
                rtpp_wi_free(netio_cf->args[ri].sigterm);
            }
            goto e1;
        }
    }

    cf->stable->rtpp_netio_cf = netio_cf;
    for (i = 0; i < SEND_THREADS; i++) {
        if (pthread_create(&(netio_cf->thread_id[i]), NULL, (void *(*)(void *))&rtpp_anetio_sthread, &netio_cf->args[i]) != 0) {
            for (ri = i - 1; ri >= 0; ri--) {
                rtpp_queue_put_item(netio_cf->args[ri].sigterm, netio_cf->args[ri].out_q);
                pthread_join(netio_cf->thread_id[ri], NULL);
            }
            for (ri = i; ri < SEND_THREADS; ri++) {
                rtpp_wi_free(netio_cf->args[ri].sigterm);
            }
            goto e1;
        }
    }

    return (netio_cf);

#if 0
e2:
    for (i = 0; i < SEND_THREADS; i++) {
        rtpp_wi_free(netio_cf->args[i].sigterm);
    }
#endif
e1:
    for (i = 0; i < SEND_THREADS; i++) {
        rtpp_queue_destroy(netio_cf->args[i].out_q);
    }
e0:
    free(netio_cf);
    return (NULL);
}