Exemplo n.º 1
0
int
main(int argc, char **argv)
{
    int i, len, timeout, controlfd, alarm_tick;
    double sptime, eptime, last_tick_time;
    unsigned long delay;
    struct cfg cf;
    char buf[256];

    memset(&cf, 0, sizeof(cf));

    init_config(&cf, argc, argv);

    seedrandom();

    init_hash_table(&cf.stable);
    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 */
    }

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

    if (cf.timeout_socket != NULL) {
	cf.timeout_handler = rtpp_notify_init(glog, cf.timeout_socket);
	if (cf.timeout_handler == NULL) {
	    rtpp_log_ewrite(RTPP_LOG_ERR, glog, "can't start notification thread");
	    exit(1);
	}
    }

    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, fatsignal);
    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.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);
	}
    }

    cf.stable.controlfd = controlfd;

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

    rtpp_command_async_init(&cf);

    sptime = 0;
    last_tick_time = 0;
    for (;;) {
        pthread_mutex_lock(&cf.glock);
        pthread_mutex_lock(&cf.sessinfo.lock);
	if (cf.rtp_nsessions > 0 || cf.sessinfo.nsessions > 0) {
	    timeout = RTPS_TICKS_MIN;
	} else {
	    timeout = TIMETICK * 1000;
        }
        pthread_mutex_unlock(&cf.sessinfo.lock);
        pthread_mutex_unlock(&cf.glock);
	eptime = getdtime();
	delay = (eptime - sptime) * 1000000.0;
	if (delay < (1000000 / POLL_LIMIT)) {
	    usleep((1000000 / POLL_LIMIT) - delay);
	    sptime = getdtime();
	} else {
	    sptime = eptime;
	}
        pthread_mutex_lock(&cf.sessinfo.lock);
        if (cf.sessinfo.nsessions > 0) {
	    i = poll(cf.sessinfo.pfds, cf.sessinfo.nsessions, timeout);
            pthread_mutex_unlock(&cf.sessinfo.lock);
	    if (i < 0 && errno == EINTR)
	        continue;
        } else {
            pthread_mutex_unlock(&cf.sessinfo.lock);
            usleep(timeout * 1000);
        }
	eptime = getdtime();
        pthread_mutex_lock(&cf.glock);
	if (cf.rtp_nsessions > 0) {
	    process_rtp_servers(&cf, eptime);
	}
        pthread_mutex_unlock(&cf.glock);
	if (eptime > last_tick_time + TIMETICK) {
	    alarm_tick = 1;
	    last_tick_time = eptime;
	} else {
	    alarm_tick = 0;
	}
        pthread_mutex_lock(&cf.glock);
	process_rtp(&cf, eptime, alarm_tick);
        pthread_mutex_unlock(&cf.glock);
    }

    exit(0);
}
Exemplo n.º 2
0
static void
rtpp_proc_async_run(void *arg)
{
    struct cfg *cf;
    double last_tick_time;
    int alarm_tick, i, ndrain, rtp_only;
    struct rtpp_proc_async_cf *proc_cf;
    long long ncycles_ref;
#ifdef RTPP_DEBUG
    int ncycles_ref_pre, last_ctick;
#endif
    struct sign_arg *s_a;
    struct rtpp_wi *wi, *wis[10];
    struct sthread_args *sender;
    double tp[4];
    struct rtpp_proc_rstats *rstats;
    struct rtpp_stats_obj *stats_cf;

    cf = (struct cfg *)arg;
    proc_cf = cf->stable->rtpp_proc_cf;
    stats_cf = cf->stable->rtpp_stats;
    rstats = &proc_cf->rstats;

    last_tick_time = 0;
    wi = rtpp_queue_get_item(proc_cf->time_q, 0);
    s_a = (struct sign_arg *)rtpp_wi_sgnl_get_data(wi, NULL);
#ifdef RTPP_DEBUG
    last_ctick = s_a->clock_tick;
    ncycles_ref_pre = s_a->ncycles_ref;
#endif
    rtpp_wi_free(wi);

    tp[0] = getdtime();
    for (;;) {
        i = rtpp_queue_get_items(proc_cf->time_q, wis, 10, 0);
        if (i <= 0) {
            continue;
        }
        i -= 1;
        s_a = (struct sign_arg *)rtpp_wi_sgnl_get_data(wis[i], NULL);
        ndrain = (s_a->ncycles_ref - ncycles_ref) / (cf->stable->target_pfreq / MAX_RTP_RATE);
#ifdef RTPP_DEBUG
        last_ctick = s_a->clock_tick;
        ncycles_ref_pre = ncycles_ref;
#endif
        ncycles_ref = s_a->ncycles_ref;
        for(; i > -1; i--) {
            rtpp_wi_free(wis[i]);
        }

        tp[1] = getdtime();
#if RTPP_DEBUG
        if (last_ctick % (unsigned int)cf->stable->target_pfreq == 0 || last_ctick < 1000) {
            rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld sptime %f, CSV: %f,%f,%f", \
              last_ctick, tp[1], (double)last_ctick / cf->stable->target_pfreq, \
              ((double)ncycles_ref / cf->stable->target_pfreq) - tp[1], tp[1]);
        }
#endif

        if (ndrain < 1) {
            ndrain = 1;
        }

#if RTPP_DEBUG
        if (ndrain > 1) {
            rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld " \
              "ncycles_ref %lld, ncycles_ref_pre %lld, ndrain %d CSV: %f,%f,%d", \
              last_ctick, ncycles_ref, ncycles_ref_pre, ndrain, \
              (double)last_ctick / cf->stable->target_pfreq, ndrain);
        }
#endif

        alarm_tick = 0;
        if (last_tick_time == 0 || last_tick_time > tp[1]) {
            last_tick_time = tp[1];
        } else if (last_tick_time + (double)TIMETICK < tp[1]) {
            alarm_tick = 1;
            last_tick_time = tp[1];
        }

        if (alarm_tick || (ncycles_ref % 7) == 0) {
            rtp_only = 0;
        } else {
            rtp_only = 1;
        }

        pthread_mutex_lock(&cf->sessinfo.lock);
        if (cf->sessinfo.nsessions > 0) {
            if (rtp_only == 0) {
                i = poll(cf->sessinfo.pfds_rtcp, cf->sessinfo.nsessions, 0);
            }
            i = poll(cf->sessinfo.pfds_rtp, cf->sessinfo.nsessions, 0);
            pthread_mutex_unlock(&cf->sessinfo.lock);
            if (i < 0 && errno == EINTR) {
                rtpp_command_async_wakeup(cf->stable->rtpp_cmd_cf);
                tp[0] = getdtime();
                continue;
            }
        } else {
            pthread_mutex_unlock(&cf->sessinfo.lock);
        }

        tp[2] = getdtime();

        sender = rtpp_anetio_pick_sender(proc_cf->op);
        if (rtp_only == 0) {
            pthread_mutex_lock(&cf->glock);
            process_rtp(cf, tp[2], alarm_tick, ndrain, sender, rstats);
        } else {
            process_rtp_only(cf, tp[2], ndrain, sender, rstats);
            pthread_mutex_lock(&cf->glock);
        }

        if (cf->rtp_nsessions > 0) {
            process_rtp_servers(cf, tp[2], sender, rstats);
        }
        pthread_mutex_unlock(&cf->glock);
        rtpp_anetio_pump_q(sender);
        rtpp_command_async_wakeup(cf->stable->rtpp_cmd_cf);
        tp[3] = getdtime();
        flush_rstats(stats_cf, rstats);

#if RTPP_DEBUG
        recfilter_apply(&proc_cf->sleep_time, tp[1] - tp[0]);
        recfilter_apply(&proc_cf->poll_time, tp[2] - tp[1]);
        recfilter_apply(&proc_cf->proc_time, tp[3] - tp[2]);
#endif
        tp[0] = tp[3];
#if RTPP_DEBUG
        if (last_ctick % (unsigned int)cf->stable->target_pfreq == 0 || last_ctick < 1000) {
#if 0
            rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld eptime %f, CSV: %f,%f,%f", \
              last_ctick, tp[3], (double)last_ctick / cf->stable->target_pfreq, tp[3] - tp[1], tp[3]);
#endif
            rtpp_log_write(RTPP_LOG_DBUG, cf->stable->glog, "run %lld eptime %f sleep_time %f poll_time %f proc_time %f CSV: %f,%f,%f,%f", \
              last_ctick, tp[3], proc_cf->sleep_time.lastval, proc_cf->poll_time.lastval, proc_cf->proc_time.lastval, \
              (double)last_ctick / cf->stable->target_pfreq, proc_cf->sleep_time.lastval, proc_cf->poll_time.lastval, proc_cf->proc_time.lastval);
        }
#endif
    }

}