Пример #1
0
struct rtpp_cmd_rcache_obj *
rtpp_cmd_rcache_ctor(struct rtpp_timed_obj *rtpp_timed_cf, double min_ttl)
{
    struct rtpp_cmd_rcache_pvt *pvt;

    pvt = rtpp_zmalloc(sizeof(struct rtpp_cmd_rcache_pvt));
    if (pvt == NULL) {
        return (NULL);
    }
    pvt->ht = rtpp_hash_table_ctor();
    if (pvt->ht == NULL) {
        goto e0;
    }
    pvt->timeout = CALL_METHOD(rtpp_timed_cf, schedule, RTPP_RCACHE_CPERD,
      rtpp_cmd_rcache_cleanup, NULL, pvt);
    if (pvt->timeout == NULL) {
        goto e0;
    }
    pvt->min_ttl = min_ttl;
    pvt->rtpp_timed_cf_save = rtpp_timed_cf;
    pvt->pub.insert = rtpp_cmd_rcache_insert;
    pvt->pub.lookup = rtpp_cmd_rcache_lookup;
    pvt->pub.dtor = rtpp_cmd_rcache_dtor;
    return (&pvt->pub);
e0:
    free(pvt);
    return (NULL);
}
Пример #2
0
struct rtpp_pcache_obj *
rtpp_pcache_ctor(void)
{
    struct rtpp_pcache_obj_full *fp;
    struct rtpp_pcache_obj *pub;
    struct rtpp_pcache_obj_priv *pvt;

    fp = rtpp_zmalloc(sizeof(struct rtpp_pcache_obj_full));
    if (fp == NULL) {
        return (NULL);
    }
    pub = &(fp->pub);
    pvt = &(fp->pvt);
    pvt->hash_table = rtpp_hash_table_ctor();
    if (pvt->hash_table == NULL) {
        free(fp);
        return (NULL);
    }
    pub->pvt = pvt;
    pub->open = &rtpp_pcache_obj_open;
    pub->read = &rtpp_pcache_obj_read;
    pub->close = &rtpp_pcache_obj_close;
    pub->dtor = &rtpp_pcache_obj_dtor;
#if defined(RTPP_DEBUG)
    assert((void *)fp == (void *)pub);
#endif
    return (pub);
}
Пример #3
0
struct rtpp_weakref_obj *
rtpp_weakref_ctor(void)
{
    struct rtpp_weakref_priv *pvt;

    pvt = rtpp_zmalloc(sizeof(struct rtpp_weakref_priv));
    if (pvt == NULL) {
        return (NULL);
    }
    pvt->ht = rtpp_hash_table_ctor(rtpp_ht_key_u64_t, RTPP_HT_NODUPS |
      RTPP_HT_DUP_ABRT);
    if (pvt->ht == NULL) {
        goto e0;
    }
    pvt->pub.dtor = &rtpp_weakref_dtor;
    pvt->pub.reg = &rtpp_weakref_reg;
    pvt->pub.get_by_idx = &rtpp_wref_get_by_idx;
    pvt->pub.unreg = &rtpp_weakref_unreg;
    pvt->pub.foreach = &rtpp_wref_foreach;
    pvt->pub.get_length = &rtpp_wref_get_length;
    pvt->pub.purge = &rtpp_wref_purge;
    return (&pvt->pub);

e0:
    free(pvt);
    return (NULL);
}
Пример #4
0
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);
}