winlin

fix #374: when terminate srs, cleanup to ensure FFMPEG quit.

... ... @@ -403,6 +403,10 @@ int SrsFFMPEG::start()
// child process: ffmpeg encoder engine.
if (pid == 0) {
// ignore the SIGINT and SIGTERM
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
// redirect logs to file.
int log_fd = -1;
int flags = O_CREAT|O_WRONLY|O_APPEND;
... ...
... ... @@ -159,6 +159,11 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
return ret;
}
void SrsIngester::dispose()
{
stop();
}
void SrsIngester::stop()
{
pthread->stop();
... ...
... ... @@ -70,6 +70,8 @@ public:
SrsIngester();
virtual ~SrsIngester();
public:
virtual void dispose();
public:
virtual int start();
virtual void stop();
// interface ISrsReusableThreadHandler.
... ...
... ... @@ -480,6 +480,7 @@ SrsServer::SrsServer()
{
signal_reload = false;
signal_gmc_stop = false;
signal_gracefully_quit = false;
pid_fd = -1;
signal_manager = NULL;
... ... @@ -519,7 +520,7 @@ void SrsServer::destroy()
close_listeners(SrsListenerHttpStream);
#ifdef SRS_AUTO_INGEST
ingester->stop();
ingester->dispose();
#endif
#ifdef SRS_AUTO_HTTP_API
... ... @@ -555,6 +556,18 @@ void SrsServer::destroy()
// and segment fault.
}
void SrsServer::dispose()
{
_srs_config->unsubscribe(this);
#ifdef SRS_AUTO_INGEST
ingester->dispose();
srs_trace("gracefully cleanup ingesters");
#endif
srs_trace("terminate server");
}
int SrsServer::initialize(ISrsServerCycle* cycle_handler)
{
int ret = ERROR_SUCCESS;
... ... @@ -831,6 +844,7 @@ int SrsServer::cycle()
srs_warn("system quit");
#else
srs_warn("main cycle terminated, system quit normally.");
dispose();
exit(0);
#endif
... ... @@ -877,9 +891,9 @@ void SrsServer::on_signal(int signo)
return;
}
if (signo == SIGTERM) {
srs_trace("user terminate program");
exit(0);
if (signo == SIGTERM && !signal_gracefully_quit) {
srs_trace("user terminate program, gracefully quit.");
signal_gracefully_quit = true;
return;
}
}
... ... @@ -903,7 +917,7 @@ int SrsServer::do_cycle()
// the deamon thread, update the time cache
while (true) {
if(handler && (ret = handler->on_cycle(conns.size())) != ERROR_SUCCESS){
if(handler && (ret = handler->on_cycle((int)conns.size())) != ERROR_SUCCESS){
srs_error("cycle handle failed. ret=%d", ret);
return ret;
}
... ... @@ -917,12 +931,18 @@ int SrsServer::do_cycle()
for (int i = 0; i < temp_max; i++) {
st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
// 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.
// 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.");
... ... @@ -930,6 +950,7 @@ int SrsServer::do_cycle()
}
#endif
// do reload the config.
if (signal_reload) {
signal_reload = false;
srs_info("get signal reload, to reload the config.");
... ...
... ... @@ -275,16 +275,22 @@ private:
*/
bool signal_reload;
bool signal_gmc_stop;
bool signal_gracefully_quit;
public:
SrsServer();
virtual ~SrsServer();
public:
private:
/**
* the destroy is for gmc to analysis the memory leak,
* if not destroy global/static data, the gmc 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:
virtual int initialize(ISrsServerCycle* cycle_handler);
... ...