int SrsServer::do_cycle()
{
    int ret = ERROR_SUCCESS;
    
    // find the max loop
    int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);
    max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES);
    
    // the deamon thread, update the time cache
    while (true) {
        for (int i = 1; i < max + 1; i++) {
            st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
        
// for gperf heap checker,
// @see: research/gperftools/heap-checker/heap_checker.cc
// if user interrupt the program, exit to check mem leak.
// but, if gperf, use reload to ensure main return normally,
// because directly exit will cause core-dump.
#ifdef SRS_AUTO_GPERF_MC
            if (signal_gmc_stop) {
                srs_warn("gmc got singal to stop server.");
                return ret;
            }
#endif
        
            if (signal_reload) {
                signal_reload = false;
                srs_info("get signal reload, to reload the config.");
                
                if ((ret = _srs_config->reload()) != ERROR_SUCCESS) {
                    srs_error("reload config failed. ret=%d", ret);
                    return ret;
                }
                srs_trace("reload config success.");
            }
            
            // update the cache time or rusage.
            if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) {
                srs_update_system_time_ms();
            }
            if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) {
                srs_update_system_rusage();
            }
            if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) {
                srs_update_proc_stat();
            }
            if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) {
                srs_update_meminfo();
            }
            if ((i % SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES) == 0) {
                srs_update_platform_info();
            }
        }
    }

    return ret;
}
示例#2
0
 int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us)
 {
     SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx;
     
     int sec = (int)(timeout_us / 1000000LL);
     int microsec = (int)(timeout_us % 1000000LL);
     
     sec = srs_max(0, sec);
     microsec = srs_max(0, microsec);
     
     struct timeval tv = { sec , microsec };
     if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) {
         return SOCKET_ERRNO();
     }
     skt->recv_timeout = timeout_us;
     
     return ERROR_SUCCESS;
 }
示例#3
0
void srs_update_system_time_ms()
{
    timeval now;
    
    gettimeofday(&now, NULL);

    // we must convert the tv_sec/tv_usec to int64_t.
    _srs_system_time_us_cache = ((int64_t)now.tv_sec) * 1000 * 1000 + (int64_t)now.tv_usec;
    
    _srs_system_time_us_cache = srs_max(0, _srs_system_time_us_cache);
}
void SrsPithyPrint::elapse()
{
    SrsStageInfo* stage = _srs_stages[stage_id];
    srs_assert(stage != NULL);
    
    int64_t diff = srs_get_system_time_ms() - previous_tick;
    diff = srs_max(0, diff);
    
    stage->elapse(diff);
    _age += diff;
    previous_tick = srs_get_system_time_ms();
}
int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv)
{
	int ret = ERROR_SUCCESS;
	
	int sample_rate = tba;
	int frame_rate = tbv;
	
	/**
	* we use a very simple time jitter detect/correct algorithm:
	* 1. delta: ensure the delta is positive and valid,
	* 	we set the delta to DEFAULT_FRAME_TIME_MS,
	* 	if the delta of time is nagative or greater than CONST_MAX_JITTER_MS.
	* 2. last_pkt_time: specifies the original packet time,
	* 	is used to detect next jitter.
	* 3. last_pkt_correct_time: simply add the positive delta, 
	* 	and enforce the time monotonically.
	*/
	u_int32_t time = msg->header.timestamp;
	int32_t delta = time - last_pkt_time;

	// if jitter detected, reset the delta.
	if (delta < 0 || delta > CONST_MAX_JITTER_MS) {
		// calc the right diff by audio sample rate
		if (msg->header.is_audio() && sample_rate > 0) {
			delta = (int32_t)(delta * 1000.0 / sample_rate);
		} else if (msg->header.is_video() && frame_rate > 0) {
			delta = (int32_t)(delta * 1.0 / frame_rate);
		} else {
			delta = DEFAULT_FRAME_TIME_MS;
		}

		// sometimes, the time is absolute time, so correct it again.
		if (delta < 0 || delta > CONST_MAX_JITTER_MS) {
			delta = DEFAULT_FRAME_TIME_MS;
		}
		
		srs_info("jitter detected, last_pts=%d, pts=%d, diff=%d, last_time=%d, time=%d, diff=%d",
			last_pkt_time, time, time - last_pkt_time, last_pkt_correct_time, last_pkt_correct_time + delta, delta);
	} else {
		srs_verbose("timestamp no jitter. time=%d, last_pkt=%d, correct_to=%d", 
			time, last_pkt_time, last_pkt_correct_time + delta);
	}
	
	last_pkt_correct_time = srs_max(0, last_pkt_correct_time + delta);
	msg->header.timestamp = last_pkt_correct_time;
	last_pkt_time = time;
	
	return ret;
}
int SrsServer::do_cycle()
{
    int ret = ERROR_SUCCESS;
    
    // find the max loop
    int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);
    max = srs_max(max, SRS_SYS_RUSAGE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_CPU_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_DISK_STAT_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_MEMINFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES);
    max = srs_max(max, SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES);
    
    // the deamon thread, update the time cache
    while (true) {
        // the interval in config.
        int heartbeat_max_resolution = (int)(_srs_config->get_heartbeat_interval() / 100);
        
        // dynamic fetch the max.
        int __max = max;
        __max = srs_max(__max, heartbeat_max_resolution);
        
        for (int i = 0; i < __max; i++) {
            st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
        
// for gperf heap checker,
// @see: research/gperftools/heap-checker/heap_checker.cc
// if user interrupt the program, exit to check mem leak.
// but, if gperf, use reload to ensure main return normally,
// because directly exit will cause core-dump.
#ifdef SRS_AUTO_GPERF_MC
            if (signal_gmc_stop) {
                srs_warn("gmc got singal to stop server.");
                return ret;
            }
#endif
        
            if (signal_reload) {
                signal_reload = false;
                srs_info("get signal reload, to reload the config.");
                
                if ((ret = _srs_config->reload()) != ERROR_SUCCESS) {
                    srs_error("reload config failed. ret=%d", ret);
                    return ret;
                }
                srs_trace("reload config success.");
            }
            
            // update the cache time or rusage.
            if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) {
                srs_info("update current time cache.");
                srs_update_system_time_ms();
            }
            if ((i % SRS_SYS_RUSAGE_RESOLUTION_TIMES) == 0) {
                srs_info("update resource info, rss.");
                srs_update_system_rusage();
            }
            if ((i % SRS_SYS_CPU_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update cpu info, cpu usage.");
                srs_update_proc_stat();
            }
            if ((i % SRS_SYS_DISK_STAT_RESOLUTION_TIMES) == 0) {
                srs_info("update disk info, disk iops.");
                srs_update_disk_stat();
            }
            if ((i % SRS_SYS_MEMINFO_RESOLUTION_TIMES) == 0) {
                srs_info("update memory info, usage/free.");
                srs_update_meminfo();
            }
            if ((i % SRS_SYS_PLATFORM_INFO_RESOLUTION_TIMES) == 0) {
                srs_info("update platform info, uptime/load.");
                srs_update_platform_info();
            }
            if ((i % SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES) == 0) {
                srs_info("update network devices info.");
                srs_update_network_devices();
            }
            if ((i % SRS_SYS_NETWORK_RTMP_SERVER_RESOLUTION_TIMES) == 0) {
                srs_info("update network rtmp server info.");
                resample_kbps(NULL);
                srs_update_rtmp_server((int)conns.size(), kbps);
            }
#ifdef SRS_AUTO_HTTP_PARSER
            if (_srs_config->get_heartbeat_enabled()) {
                if ((i % heartbeat_max_resolution) == 0) {
                    srs_info("do http heartbeat, for internal server to report.");
                    http_heartbeat->heartbeat();
                }
            }
#endif
            srs_info("server main thread loop");
        }
    }

    return ret;
}