From a6f88805f351c093607a46148dd9114bd259966a Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 29 Jan 2020 14:42:18 +0800 Subject: [PATCH 1/3] Remove test code --- trunk/src/app/srs_app_source.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 94579de4b..f5acb05da 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1687,7 +1687,6 @@ srs_error_t SrsSourceManager::fetch_or_create(SrsRequest* r, ISrsSourceHandler* if ((err = source->initialize(r, h)) != srs_success) { return srs_error_wrap(err, "init source %s", r->get_stream_url().c_str()); } - srs_usleep(10 * SRS_UTIME_SECONDS); pool[stream_url] = source; From 23ece94064b1d18a94e219e3bd26e0d72f9cc0b8 Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 29 Jan 2020 20:22:28 +0800 Subject: [PATCH 2/3] Fix #1206, dispose ingester while server quiting. 3.0.111 --- README.md | 2 ++ trunk/src/app/srs_app_ffmpeg.cpp | 5 +++++ trunk/src/app/srs_app_ffmpeg.hpp | 1 + trunk/src/app/srs_app_ingest.cpp | 32 ++++++++++++++++++++++++++++--- trunk/src/app/srs_app_ingest.hpp | 6 ++++++ trunk/src/app/srs_app_process.cpp | 25 ++++++++++++++++++++++++ trunk/src/app/srs_app_process.hpp | 2 ++ trunk/src/app/srs_app_server.cpp | 14 ++++++-------- trunk/src/core/srs_core.hpp | 2 +- 9 files changed, 77 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index e792e3df1..c1a563140 100755 --- a/README.md +++ b/README.md @@ -146,6 +146,7 @@ For previous versions, please read: ## V3 changes +* v3.0, 2020-01-29, Fix [#1206][bug #1206], dispose ingester while server quiting. 3.0.111 * v3.0, 2020-01-28, Fix [#1230][bug #1230], racing condition in source fetch or create. 3.0.110 * v3.0, 2020-01-27, Fix [#1303][bug #1303], do not dispatch previous meta when not publishing. 3.0.109 * v3.0, 2020-01-26, Allow use libst.so for ST is MPL license. @@ -1632,6 +1633,7 @@ Winlin [bug #607]: https://github.com/ossrs/srs/issues/607 [bug #1303]: https://github.com/ossrs/srs/issues/1303 [bug #1230]: https://github.com/ossrs/srs/issues/1230 +[bug #1206]: https://github.com/ossrs/srs/issues/1206 [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx [exo #828]: https://github.com/google/ExoPlayer/pull/828 diff --git a/trunk/src/app/srs_app_ffmpeg.cpp b/trunk/src/app/srs_app_ffmpeg.cpp index 1712f617d..5c79bf992 100644 --- a/trunk/src/app/srs_app_ffmpeg.cpp +++ b/trunk/src/app/srs_app_ffmpeg.cpp @@ -418,6 +418,11 @@ void SrsFFMPEG::fast_stop() process->fast_stop(); } +void SrsFFMPEG::fast_kill() +{ + process->fast_kill(); +} + #endif diff --git a/trunk/src/app/srs_app_ffmpeg.hpp b/trunk/src/app/srs_app_ffmpeg.hpp index a158d957e..a837fdf24 100644 --- a/trunk/src/app/srs_app_ffmpeg.hpp +++ b/trunk/src/app/srs_app_ffmpeg.hpp @@ -83,6 +83,7 @@ public: virtual void stop(); public: virtual void fast_stop(); + virtual void fast_kill(); }; #endif diff --git a/trunk/src/app/srs_app_ingest.cpp b/trunk/src/app/srs_app_ingest.cpp index edaaa0c8a..453c48c6e 100644 --- a/trunk/src/app/srs_app_ingest.cpp +++ b/trunk/src/app/srs_app_ingest.cpp @@ -97,11 +97,17 @@ void SrsIngesterFFMPEG::fast_stop() ffmpeg->fast_stop(); } +void SrsIngesterFFMPEG::fast_kill() +{ + ffmpeg->fast_kill(); +} + SrsIngester::SrsIngester() { _srs_config->subscribe(this); expired = false; + disposed = false; trd = new SrsDummyCoroutine(); pprint = SrsPithyPrint::create_ingester(); @@ -117,11 +123,18 @@ SrsIngester::~SrsIngester() void SrsIngester::dispose() { + if (disposed) { + return; + } + disposed = true; + // first, use fast stop to notice all FFMPEG to quit gracefully. fast_stop(); + + srs_usleep(100 * SRS_UTIME_MILLISECONDS); - // then, use stop to wait FFMPEG quit one by one and send SIGKILL if needed. - stop(); + // then, use fast kill to ensure FFMPEG quit. + fast_kill(); } srs_error_t SrsIngester::start() @@ -166,6 +179,19 @@ void SrsIngester::fast_stop() } } +void SrsIngester::fast_kill() +{ + std::vector::iterator it; + for (it = ingesters.begin(); it != ingesters.end(); ++it) { + SrsIngesterFFMPEG* ingester = *it; + ingester->fast_kill(); + } + + if (!ingesters.empty()) { + srs_trace("fast kill all ingesters ok."); + } +} + // when error, ingester sleep for a while and retry. // ingest never sleep a long time, for we must start the stream ASAP. #define SRS_AUTO_INGESTER_CIMS (3 * SRS_UTIME_SECONDS) @@ -174,7 +200,7 @@ srs_error_t SrsIngester::cycle() { srs_error_t err = srs_success; - while (true) { + while (!disposed) { if ((err = do_cycle()) != srs_success) { srs_warn("Ingester: Ignore error, %s", srs_error_desc(err).c_str()); srs_freep(err); diff --git a/trunk/src/app/srs_app_ingest.hpp b/trunk/src/app/srs_app_ingest.hpp index 2bef9ba7b..4118d77fb 100644 --- a/trunk/src/app/srs_app_ingest.hpp +++ b/trunk/src/app/srs_app_ingest.hpp @@ -60,6 +60,7 @@ public: virtual srs_error_t cycle(); // @see SrsFFMPEG.fast_stop(). virtual void fast_stop(); + virtual void fast_kill(); }; // Ingest file/stream/device, @@ -75,6 +76,8 @@ private: // Whether the ingesters are expired, for example, the listen port changed, // all ingesters must be restart. bool expired; + // Whether already disposed. + bool disposed; public: SrsIngester(); virtual ~SrsIngester(); @@ -84,7 +87,10 @@ public: virtual srs_error_t start(); virtual void stop(); private: + // Notify FFMPEG to fast stop. virtual void fast_stop(); + // When SRS quit, directly kill FFMPEG after fast stop. + virtual void fast_kill(); // Interface ISrsReusableThreadHandler. public: virtual srs_error_t cycle(); diff --git a/trunk/src/app/srs_app_process.cpp b/trunk/src/app/srs_app_process.cpp index 8975c0b69..2b50b9583 100644 --- a/trunk/src/app/srs_app_process.cpp +++ b/trunk/src/app/srs_app_process.cpp @@ -327,3 +327,28 @@ void SrsProcess::fast_stop() return; } +void SrsProcess::fast_kill() +{ + int ret = ERROR_SUCCESS; + + if (!is_started) { + return; + } + + if (pid <= 0) { + return; + } + + if (kill(pid, SIGKILL) < 0) { + ret = ERROR_SYSTEM_KILL; + srs_warn("ignore fast kill process failed, pid=%d. ret=%d", pid, ret); + return; + } + + // Try to wait pid to avoid zombie FFMEPG. + int status = 0; + waitpid(pid, &status, WNOHANG); + + return; +} + diff --git a/trunk/src/app/srs_app_process.hpp b/trunk/src/app/srs_app_process.hpp index 09e071aec..13990e430 100644 --- a/trunk/src/app/srs_app_process.hpp +++ b/trunk/src/app/srs_app_process.hpp @@ -91,6 +91,8 @@ public: // when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N] // but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS]. virtual void fast_stop(); + // Directly kill process, never use it except server quiting. + virtual void fast_kill(); }; #endif diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 2a3039f1a..8768ff642 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -520,7 +520,8 @@ void SrsServer::dispose() close_listeners(SrsListenerRtsp); close_listeners(SrsListenerFlv); - // @remark don't dispose ingesters, for too slow. + // Fast stop to notify FFMPEG to quit, wait for a while then fast kill. + ingester->dispose(); // dispose the source for hls and dvr. _srs_sources->dispose(); @@ -856,17 +857,14 @@ void SrsServer::on_signal(int signo) srs_trace("gmc is on, main cycle will terminate normally."); signal_gmc_stop = true; #else - srs_trace("user terminate program"); -#ifdef SRS_AUTO_MEM_WATCH + #ifdef SRS_AUTO_MEM_WATCH srs_memory_report(); + #endif #endif - exit(0); -#endif - return; } - if (signo == SRS_SIGNAL_GRACEFULLY_QUIT && !signal_gracefully_quit) { - srs_trace("user terminate program, gracefully quit."); + if ((signo == SIGINT || signo == SRS_SIGNAL_GRACEFULLY_QUIT) && !signal_gracefully_quit) { + srs_trace("sig=%d, user terminate program, gracefully quit", signo); signal_gracefully_quit = true; return; } diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index e3d8c838e..dab42c72d 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 110 +#define VERSION_REVISION 111 // The macros generated by configure script. #include From 41f3925abc692f52ad32bd64044bc823a351128f Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 29 Jan 2020 20:28:37 +0800 Subject: [PATCH 3/3] Add version file for srs3 --- trunk/src/core/srs_core.hpp | 3 ++- trunk/src/core/srs_core_version3.hpp | 29 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 trunk/src/core/srs_core_version3.hpp diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index dab42c72d..9a60cb8c5 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,8 @@ // The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 111 +#include +#define VERSION_REVISION SRS_VERSION3_REVISION // The macros generated by configure script. #include diff --git a/trunk/src/core/srs_core_version3.hpp b/trunk/src/core/srs_core_version3.hpp new file mode 100644 index 000000000..4a0cc1fd4 --- /dev/null +++ b/trunk/src/core/srs_core_version3.hpp @@ -0,0 +1,29 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2020 Winlin + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SRS_CORE_VERSION3_HPP +#define SRS_CORE_VERSION3_HPP + +#define SRS_VERSION3_REVISION 111 + +#endif