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; }
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; }
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; }