diff --git a/trunk/src/app/srs_app_ffmpeg.cpp b/trunk/src/app/srs_app_ffmpeg.cpp index 7da9b3c501..92dda2197f 100644 --- a/trunk/src/app/srs_app_ffmpeg.cpp +++ b/trunk/src/app/srs_app_ffmpeg.cpp @@ -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; diff --git a/trunk/src/app/srs_app_ingest.cpp b/trunk/src/app/srs_app_ingest.cpp index c2c6234392..986d5af233 100644 --- a/trunk/src/app/srs_app_ingest.cpp +++ b/trunk/src/app/srs_app_ingest.cpp @@ -159,6 +159,11 @@ int SrsIngester::parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest return ret; } +void SrsIngester::dispose() +{ + stop(); +} + void SrsIngester::stop() { pthread->stop(); diff --git a/trunk/src/app/srs_app_ingest.hpp b/trunk/src/app/srs_app_ingest.hpp index 7a14a8dac6..d10e1e4148 100644 --- a/trunk/src/app/srs_app_ingest.hpp +++ b/trunk/src/app/srs_app_ingest.hpp @@ -69,6 +69,8 @@ class SrsIngester : public ISrsReusableThreadHandler, public ISrsReloadHandler public: SrsIngester(); virtual ~SrsIngester(); +public: + virtual void dispose(); public: virtual int start(); virtual void stop(); diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 7c092949af..8e945a4950 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -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."); diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 587adc8f05..d9013a6259 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -275,16 +275,22 @@ class SrsServer : virtual public ISrsReloadHandler */ 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);