1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

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

This commit is contained in:
winlin 2015-05-30 09:58:17 +08:00
parent db57a519a9
commit 567d84e997
5 changed files with 49 additions and 11 deletions

View file

@ -403,6 +403,10 @@ int SrsFFMPEG::start()
// child process: ffmpeg encoder engine. // child process: ffmpeg encoder engine.
if (pid == 0) { if (pid == 0) {
// ignore the SIGINT and SIGTERM
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
// redirect logs to file. // redirect logs to file.
int log_fd = -1; int log_fd = -1;
int flags = O_CREAT|O_WRONLY|O_APPEND; int flags = O_CREAT|O_WRONLY|O_APPEND;

View file

@ -159,6 +159,11 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest
return ret; return ret;
} }
void SrsIngester::dispose()
{
stop();
}
void SrsIngester::stop() void SrsIngester::stop()
{ {
pthread->stop(); pthread->stop();

View file

@ -69,6 +69,8 @@ private:
public: public:
SrsIngester(); SrsIngester();
virtual ~SrsIngester(); virtual ~SrsIngester();
public:
virtual void dispose();
public: public:
virtual int start(); virtual int start();
virtual void stop(); virtual void stop();

View file

@ -480,6 +480,7 @@ SrsServer::SrsServer()
{ {
signal_reload = false; signal_reload = false;
signal_gmc_stop = false; signal_gmc_stop = false;
signal_gracefully_quit = false;
pid_fd = -1; pid_fd = -1;
signal_manager = NULL; signal_manager = NULL;
@ -519,7 +520,7 @@ void SrsServer::destroy()
close_listeners(SrsListenerHttpStream); close_listeners(SrsListenerHttpStream);
#ifdef SRS_AUTO_INGEST #ifdef SRS_AUTO_INGEST
ingester->stop(); ingester->dispose();
#endif #endif
#ifdef SRS_AUTO_HTTP_API #ifdef SRS_AUTO_HTTP_API
@ -555,6 +556,18 @@ void SrsServer::destroy()
// and segment fault. // 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 SrsServer::initialize(ISrsServerCycle* cycle_handler)
{ {
int ret = ERROR_SUCCESS; int ret = ERROR_SUCCESS;
@ -831,6 +844,7 @@ int SrsServer::cycle()
srs_warn("system quit"); srs_warn("system quit");
#else #else
srs_warn("main cycle terminated, system quit normally."); srs_warn("main cycle terminated, system quit normally.");
dispose();
exit(0); exit(0);
#endif #endif
@ -877,9 +891,9 @@ void SrsServer::on_signal(int signo)
return; return;
} }
if (signo == SIGTERM) { if (signo == SIGTERM && !signal_gracefully_quit) {
srs_trace("user terminate program"); srs_trace("user terminate program, gracefully quit.");
exit(0); signal_gracefully_quit = true;
return; return;
} }
} }
@ -903,7 +917,7 @@ int SrsServer::do_cycle()
// the deamon thread, update the time cache // the deamon thread, update the time cache
while (true) { 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); srs_error("cycle handle failed. ret=%d", ret);
return ret; return ret;
} }
@ -918,11 +932,17 @@ int SrsServer::do_cycle()
for (int i = 0; i < temp_max; i++) { for (int i = 0; i < temp_max; i++) {
st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000); st_usleep(SRS_SYS_CYCLE_INTERVAL * 1000);
// for gperf heap checker, // gracefully quit for SIGINT or SIGTERM.
// @see: research/gperftools/heap-checker/heap_checker.cc if (signal_gracefully_quit) {
// if user interrupt the program, exit to check mem leak. srs_trace("cleanup for gracefully terminate.");
// but, if gperf, use reload to ensure main return normally, return ret;
// 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 #ifdef SRS_AUTO_GPERF_MC
if (signal_gmc_stop) { if (signal_gmc_stop) {
srs_warn("gmc got singal to stop server."); srs_warn("gmc got singal to stop server.");
@ -930,6 +950,7 @@ int SrsServer::do_cycle()
} }
#endif #endif
// do reload the config.
if (signal_reload) { if (signal_reload) {
signal_reload = false; signal_reload = false;
srs_info("get signal reload, to reload the config."); srs_info("get signal reload, to reload the config.");

View file

@ -275,16 +275,22 @@ private:
*/ */
bool signal_reload; bool signal_reload;
bool signal_gmc_stop; bool signal_gmc_stop;
bool signal_gracefully_quit;
public: public:
SrsServer(); SrsServer();
virtual ~SrsServer(); virtual ~SrsServer();
public: private:
/** /**
* the destroy is for gmc to analysis the memory leak, * the destroy is for gmc to analysis the memory leak,
* if not destroy global/static data, the gmc will warning memory leak. * if not destroy global/static data, the gmc will warning memory leak.
* in service, server never destroy, directly exit when restart. * in service, server never destroy, directly exit when restart.
*/ */
virtual void destroy(); 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() // server startup workflow, @see run_master()
public: public:
virtual int initialize(ISrsServerCycle* cycle_handler); virtual int initialize(ISrsServerCycle* cycle_handler);