SRS之SrsServer::cycle()
1. SrsServer 相关类定义
1.1 SrsServer 类定义
/**
* SRS RTMP server, initialize and listen,
* start connection service thread, destroy client.
*/
class SrsServer : virtual public ISrsReloadHandler
, virtual public ISrsSourceHandler
, virtual public IConnectionManager
{
private:
#ifdef SRS_AUTO_HTTP_API
// TODO: FIXME: rename to http_api
SrsHttpServeMux* http_api_mux;
#endif
#ifdef SRS_AUTO_HTTP_SERVER
SrsHttpServer* http_server;
#endif
#ifdef SRS_AUTO_HTTP_CORE
SrsHttpHeartbeat* http_heartbeat;
#endif
#ifdef SRS_AUTO_INGEST
SrsIngester* ingester;
#endif
private:
/**
* the pid file fd, lock the file write when server is running.
* @remark the init.d script should cleanup the pid file, when stop service,
* for the server never delete the file; when system startup, the pid
* in pid file maybe valid but the process is not SRS, the init.d script
* will never start server.
*/
int pid_fd;
/**
* all connections, connection manager
*/
std::vector<SrsConnection*> conns;
/**
* all listeners, listener manager.
*/
std::vector<SrsListener*> listeners;
/**
* signal manager which convert signal to io message.
*/
SrsSignalManager* signal_manager;
/**
* handle in server cycle.
*/
ISrsServerCycle* handler;
/**
* user send the signal, convert to variable.
*/
bool signal_reload;
bool signal_gmc_stop;
bool signal_gracefully_quit;
/* parent pid for asprocess. */
int ppid;
public:
SrsServer();
virtual ~SrsServer();
private:
/**
* the destroy is for gmc to analysis the memory leak,
* if not destroy global/static data, the gmc will will warning memory leak.
* in service, server never destroy, directly exit when restart.
*/
virtual void destroy();
/**
* when SIGTERM, SRS should do cleanup, for example,
* to stop all ingesters, cleanup HLS and dvr.
*/
virtual void dispose();
// server startup workflow, @see run_master()
public:
/**
* initialize server with callback handler.
* @remark user must free the cycle handler.
*/
virtual int initialize(ISrsServerCycle* cycle_handler);
virtual int initialize_st();
virtual int initialize_signal();
virtual int acquire_pid_file();
virtual int listen();
virtual int register_signal();
virtual int http_handle();
virtual int ingest();
virtual int cycle();
// IConnectionManager
public:
/**
* callback for connection to remove itself.
* when connection thread cycle terminatedk, callback this to delete connection.
* @see SrsConnection.on_thread_stop().
*/
virtual void remove(SrsConnection* conn);
// server utilities.
public:
/**
* callback for signal manager got a signal.
* the signal manager convert signal to io message,
* whatever, we will got the signo like the orignal signal(int signo) handler.
* @remark, directly exit for SIGTERM.
* @remark, do reload for SIGNAL_RELOAD.
* @remark, for SIGINT and SIGUSR2:
* no gmc, directly exit.
* for gmc, set the variable signal_gmc_stop, the cycle will return
* and cleanup for gmc.
*/
virtual void on_signal(int signo);
private:
/**
* the server thread main cycle,
* update the global static data, for instance, the current time,
* the cpu/mem/network statistic.
*/
virtual int do_cycle();
/**
* listen at specified protocol.
*/
virtual int listen_rtmp();
virtual int listen_http_api();
virtual int listen_http_stream();
virtual int listen_stream_caster();
/**
* close the listeners for specified type,
* remove the listen object from manager.
*/
virtual void close_listeners(SrsListenerType type);
/**
* resample the server kbs.
*/
virtual void resample_kbps();
// internal only
public:
/**
* when listener got a fd, notice server to accept it.
* @param type, the client type, used to create concreate connection,
* for instance RTMP connection to server client.
* @param client_stfd, the client fd in st boxed, the underlayer fd.
*/
virtual int accept_client(SrsListenerType type, st_netfd_t client_stfd);
// interface ISrsReloadHandler.
public:
virtual int on_reload_listen();
virtual int on_reload_pid();
virtual int on_reload_vhost_added(std::string vhost);
virtual int on_reload_vhost_removed(std::string vhost);
virtual int on_reload_http_api_enabled();
virtual int on_reload_http_api_disabled();
virtual int on_reload_http_stream_enabled();
virtual int on_reload_http_stream_disabled();
virtual int on_reload_http_stream_updated();
// interface ISrsSourceHandler
public:
virtual int on_publish(SrsSource* s, SrsRequest* r);
virtual void on_unpublish(SrsSource* s, SrsRequest* r);
};
1.2 ISrsReloadHandler 类定义
/**
* the handler for config reload.
* when reload callback, the config is updated yet.
*
* features not support reload,
* @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures
*/
class ISrsReloadHandler
{
public:
ISrsReloadHandler();
virtual ~ISrsReloadHandler();
public:
virtual int on_reload_utc_time();
virtual int on_reload_max_conns();
virtual int on_reload_listen();
virtual int on_reload_pid();
virtual int on_reload_log_tank();
virtual int on_reload_log_level();
virtual int on_reload_log_file();
virtual int on_reload_pithy_print();
virtual int on_reload_http_api_enabled();
virtual int on_reload_http_api_disabled();
virtual int on_reload_http_stream_enabled();
virtual int on_reload_http_stream_disabled();
virtual int on_reload_http_stream_updated();
public:
// TODO: FIXME: should rename to http_static
virtual int on_reload_vhost_http_updated();
virtual int on_reload_vhost_http_remux_updated(std::string vhost);
virtual int on_reload_vhost_added(std::string vhost);
virtual int on_reload_vhost_removed(std::string vhost);
virtual int on_reload_vhost_atc(std::string vhost);
virtual int on_reload_vhost_gop_cache(std::string vhost);
virtual int on_reload_vhost_queue_length(std::string vhost);
virtual int on_reload_vhost_time_jitter(std::string vhost);
virtual int on_reload_vhost_mix_correct(std::string vhost);
virtual int on_reload_vhost_forward(std::string vhost);
virtual int on_reload_vhost_hls(std::string vhost);
virtual int on_reload_vhost_hds(std::string vhost);
virtual int on_reload_vhost_dvr(std::string vhost);
virtual int on_reload_vhost_mr(std::string vhost);
virtual int on_reload_vhost_mw(std::string vhost);
virtual int on_reload_vhost_smi(std::string vhost);
virtual int on_reload_vhost_tcp_nodelay(std::string vhost);
virtual int on_reload_vhost_realtime(std::string vhost);
virtual int on_reload_vhost_p1stpt(std::string vhost);
virtual int on_reload_vhost_pnt(std::string vhost);
virtual int on_reload_vhost_chunk_size(std::string vhost);
virtual int on_reload_vhost_transcode(std::string vhost);
virtual int on_reload_ingest_removed(std::string vhost, std::string ingest_id);
virtual int on_reload_ingest_added(std::string vhost, std::string ingest_id);
virtual int on_reload_ingest_updated(std::string vhost, std::string ingest_id);
virtual int on_reload_user_info();
};
1.3 ISrsSourceHandler 类定义
/**
* the handler to handle the event of srs source.
* for example, the http flv streaming module handle the event and
* mount http when rtmp start publishing.
*/
class ISrsSourceHandler
{
public:
ISrsSourceHandler();
virtual ~ISrsSourceHandler();
public:
/**
* when stream start publish, mount stream.
*/
virtual int on_publish(SrsSource* s, SrsRequest* r) = 0;
/**
* when stream stop publish, unmount stream.
*/
virtual void on_unpublish(SrsSource* s, SrsRequest* r) = 0;
};
1.4 IConnectionManager
/**
* the manager for connection.
*/
class IConnectionManager
{
public:
IConnectionManager();
virtual ~IConnectionManager();
public:
/**
* remove the specified connection.
*/
virtual void remove(SrsConnection* c) = 0;
};
SrsServer 和 ISrsReloadHandler、ISrsSourceHandler 以及 IConnectionManager 之间的关系(继承)

2. int SrsServer::cycle
位于 srs_app_server.cpp:
int SrsServer::cycle()
{
int ret = ERROR_SUCCESS;
/* 开始进入 SRS 的主循环 */
ret = do_cycle();
#ifdef SRS_AUTO_GPERF_MC
destroy();
// remark, for gmc, never invoke the exit().
srs_warn("sleep a long time for system st-threads to cleanup.");
st_usleep(3 * 1000 * 1000);
srs_warn("system quit");
#else
// normally quit with neccessary cleanup by dispost().
srs_warn("main cycle terminated, system quit normally.");
dispose();
srs_trace("srs terminated");
// for valgrind to detect.
srs_freep(_srs_config);
srs_freep(_srs_log);
exit(0);
#endif
return ret;
}
2.1 SrsServer::do_cycle
int SrsServer::do_cycle()
{
int ret = ERROR_SUCCESS;
// find the max loop
int max = srs_max(0, SRS_SYS_TIME_RESOLUTION_MS_TIMES);
#ifdef SRS_AUTO_STAT
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);
#endif
// for asprocess.
bool asprocess = _srs_config->get_asprocess();
// the daemon thread, update the time cache
while (true) {
/* 这里 handler 初始化为 NULL,所以忽略 */
if (handler && (ret = handler->on_cycle((int)conns.size())) != ERROR_SUCCESS) {
srs_error("cycle handle failed. ret=%d", ret);
return ret;
}
// the interval in config.
int heartbeat_max_resolution = (int)(_srs_config->get_heartbeat_interval() \
/ SRS_SYS_CYCLE_INTERVAL);
// dynamic fetch the max.
int temp_max = max;
temp_max = srs_max(temp_max, heartbeat_max_resolution);
for (int i = 0; i < temp_max; i++) {
/* 主线程进入休眠,调度其他线程运行,比如调度 conn 线程,接收
* 客户端的连接 */
st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
// asprocess check.
if (asprocess && ::getppid() != ppid) {
srs_warn("asprocess ppid changed from %d to %d", ppid, ::getppid());
return ret;
}
// gracefully quit for SIGINT or SIGTERM.
if (signal_gracefully_quit) {
srs_trace("cleanup for gracefully terminate");
return ret;
}
// 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
// do reload the config.
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.");
}
// notice the stream sources to cycle.
if ((ret = SrsSource::cycle_all()) != ERROR_SUCCESS) {
return ret;
}
// update the cache time
if ((i % SRS_SYS_TIME_RESOLUTION_MS_TIMES) == 0) {
srs_info("update current time cache.");
srs_update_system_time_ms();
}
#ifdef SRS_AUTO_STAT
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 server kbps info.");
resample_kbps();
}
#ifdef SRS_AUTO_HTTP_CORE
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
#endif
srs_info("server main thread loop");
}
}
}
在该函数中,该主线程循环进行休眠,以便调度其他线程运行。
SRS之SrsServer::cycle()的更多相关文章
- SRS之播放推流视频
1. 综述 首先,推流直播的配置文件如下: # rtmp.conf listen 1935; max_connections 1000; daemon off; srs_log_tank consol ...
- SRS之HLS部署实例源码分析
1. 综述 SRS 关于 HLS 的具体配置可见: HLS部署实例 SRS 关于 hls 的配置文件内容如下: listen 1935; max_connections 1000; daemon of ...
- SRS之SrsRtmpConn::publishing详解
1. SrsRtmpConn::publishing int SrsRtmpConn::publishing(SrsSource* source) { int ret = ERROR_SUCCESS; ...
- SRS之RTMP的TCP线程(即监听线程)
本文分析的是 SRS 针对 rtmp 的端口建立的 tcp 线程.具体建立过程: SRS之监听端口的管理:RTMP RTMP 的 TCP 线程中各个类之间 handler 的关系图 1. RTMP之T ...
- SRS之信号的管理:SrsSignalManager
1. 综述 SRS 中使用了 State Threads 协程库,该库对信号的处理是将信号事件转换为 I/O 事件.主要做法是:对关注的信号设置同样地信号处理函数 sig_catcher(),该函数捕 ...
- SRS之监听端口的管理:RTMP
1. 监听端口管理的入口函数 监听端口的管理入口在 run_master 函数中,如下: int run_master() { ... if ((ret = _srs_server->liste ...
- SRS+flv.js打造兼容性较高的直播、点播平台
**************************************************************************************************** ...
- SRS之接收推流线程:recv
SrsPublishRecvThread.SrsRecvThread.SrsReusableThread2.SrsThread 之间的关系图 1. recv 线程函数:SrsThread::threa ...
- SRS之SrsRtmpConn::service_cycle详解
1. SrsRtmpConn::service_cycle 当服务器在 conn 线程的开始调用 connect_app 函数接收并解析客户端发送的 connect 消息后,调用该 service_c ...
随机推荐
- Spark 源码和应用开发环境的构建
引言 Spark 现在无疑是大数据领域最热门的技术之一,读者很容易搜索到介绍如何应用 Spark 技术的文章,但是作为开发人员,在了解了应用的概念之后,更习惯的是打开开发环境,开发一些应用来更深入的学 ...
- vue进阶:vuex(数据池)
非父子组件传值 vuex 一.非父子组件传值 基于父子组件通信与传值实现非父子组件传值的示例关键代码: <template> <div> <!-- 学员展示 --> ...
- form表单相关
<input> 元素 <input> 元素是最重要的表单元素. <input> 元素有很多形态,根据不同的 type 属性. 这是本章中使用的类型: 类型 描述 t ...
- 常用的Java工具类——十六种
常用的Java工具类——十六种 在Java中,工具类定义了一组公共方法,这篇文章将介绍Java中使用最频繁及最通用的Java工具类.以下工具类.方法按使用流行度排名,参考数据来源于Github上随机选 ...
- sqoop 安装
Sqoop是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql.postgresql...)间进行数据的传递,可以将一个关系型数据库(例如 : MySQL ,Oracle , ...
- 如何解决comctl32.dll文件丢失的问题?
有些Win7系统用户在电脑开机时,系统会出现提示找不到comctl32.dll文件的情况,遇到这个问题我们该怎么去解决呢?好系统重装助手下面就来告诉你方法. Win7系统开机提示找不到comctl32 ...
- Jetson TX1 安装ROS操作系统
直接按照官网上的步骤安装即可,其中会出现很多bug,主要是依赖库安装的问题,添加清华源和中科大源,(注意:中科大源会有些问题)需要apt-get update 和 apt-get upgrade更新库 ...
- Oracle【多表查询操作(SQL92&SQL99)】
多表联合查询:需要获取的数据分布在多张表中 SQL92: --笛卡尔积:将多个表的数据进行一一对应,所得的结果为多表的笛卡尔积 select * from emp; select * from dep ...
- 论文笔记:Learning Region Features for Object Detection
中心思想 继Relation Network实现可学习的nms之后,MSRA的大佬们觉得目标检测器依然不够fully learnable,这篇文章类似之前的Deformable ROI Pooling ...
- Codeforce Round #424
A 略 B 略 C: 先对Ai数列预处理前缀和 然后把Bi的每个都加一次 最终得到的结果为ans[sum]++; 最后如果有一个ans[sum]>=k即满足所有K个条件就输出(注意!!前缀和要进 ...