for #374, use SIGINT then SIGKILL to try to kill FFMPEG gracefullly.
正在显示
4 个修改的文件
包含
79 行增加
和
21 行删除
@@ -35,6 +35,7 @@ using namespace std; | @@ -35,6 +35,7 @@ using namespace std; | ||
35 | #include <srs_kernel_error.hpp> | 35 | #include <srs_kernel_error.hpp> |
36 | #include <srs_kernel_log.hpp> | 36 | #include <srs_kernel_log.hpp> |
37 | #include <srs_app_config.hpp> | 37 | #include <srs_app_config.hpp> |
38 | +#include <srs_app_utility.hpp> | ||
38 | 39 | ||
39 | #ifdef SRS_AUTO_FFMPEG_STUB | 40 | #ifdef SRS_AUTO_FFMPEG_STUB |
40 | 41 | ||
@@ -509,24 +510,14 @@ void SrsFFMPEG::stop() | @@ -509,24 +510,14 @@ void SrsFFMPEG::stop() | ||
509 | // when rewind, upstream will stop publish(unpublish), | 510 | // when rewind, upstream will stop publish(unpublish), |
510 | // unpublish event will stop all ffmpeg encoders, | 511 | // unpublish event will stop all ffmpeg encoders, |
511 | // then publish will start all ffmpeg encoders. | 512 | // then publish will start all ffmpeg encoders. |
512 | - if (pid > 0) { | ||
513 | - if (kill(pid, SIGKILL) < 0) { | ||
514 | - srs_warn("kill the encoder failed, ignored. pid=%d", pid); | ||
515 | - } | ||
516 | - | ||
517 | - // wait for the ffmpeg to quit. | ||
518 | - // ffmpeg will gracefully quit if signal is: | ||
519 | - // 1) SIGHUP 2) SIGINT 3) SIGQUIT | ||
520 | - // other signals, directly exit(123), for example: | ||
521 | - // 9) SIGKILL 15) SIGTERM | ||
522 | - int status = 0; | ||
523 | - if (waitpid(pid, &status, 0) < 0) { | ||
524 | - srs_warn("wait the encoder quit failed, ignored. pid=%d", pid); | 513 | + int ret = srs_kill_forced(pid); |
514 | + if (ret != ERROR_SUCCESS) { | ||
515 | + srs_warn("ignore kill the encoder failed, pid=%d. ret=%d", pid, ret); | ||
516 | + return; | ||
525 | } | 517 | } |
526 | 518 | ||
527 | - srs_trace("stop the encoder success. pid=%d", pid); | ||
528 | - pid = -1; | ||
529 | - } | 519 | + // terminated, set started to false to stop the cycle. |
520 | + started = false; | ||
530 | } | 521 | } |
531 | 522 | ||
532 | #endif | 523 | #endif |
@@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
27 | #include <unistd.h> | 27 | #include <unistd.h> |
28 | #include <ifaddrs.h> | 28 | #include <ifaddrs.h> |
29 | #include <arpa/inet.h> | 29 | #include <arpa/inet.h> |
30 | +#include <signal.h> | ||
30 | 31 | ||
31 | #ifdef SRS_OSX | 32 | #ifdef SRS_OSX |
32 | #include <sys/sysctl.h> | 33 | #include <sys/sysctl.h> |
@@ -222,6 +223,63 @@ void srs_parse_endpoint(string ip_port, string& ip, int& port) | @@ -222,6 +223,63 @@ void srs_parse_endpoint(string ip_port, string& ip, int& port) | ||
222 | port = ::atoi(the_port.c_str()); | 223 | port = ::atoi(the_port.c_str()); |
223 | } | 224 | } |
224 | 225 | ||
226 | +#define SRS_PROCESS_QUIT_TIMEOUT_MS 1000 | ||
227 | +int srs_kill_forced(int& pid) | ||
228 | +{ | ||
229 | + int ret = ERROR_SUCCESS; | ||
230 | + | ||
231 | + if (pid <= 0) { | ||
232 | + return ret; | ||
233 | + } | ||
234 | + | ||
235 | + // first, try kill by SIGINT. | ||
236 | + if (kill(pid, SIGINT) < 0) { | ||
237 | + return ERROR_SYSTEM_KILL; | ||
238 | + } | ||
239 | + | ||
240 | + // wait to quit. | ||
241 | + srs_trace("send SIGINT to pid=%d", pid); | ||
242 | + for (int i = 0; i < SRS_PROCESS_QUIT_TIMEOUT_MS / 10; i++) { | ||
243 | + int status = 0; | ||
244 | + pid_t qpid = -1; | ||
245 | + if ((qpid = waitpid(pid, &status, WNOHANG)) < 0) { | ||
246 | + return ERROR_SYSTEM_KILL; | ||
247 | + } | ||
248 | + | ||
249 | + // 0 is not quit yet. | ||
250 | + if (qpid == 0) { | ||
251 | + st_usleep(10 * 1000); | ||
252 | + continue; | ||
253 | + } | ||
254 | + | ||
255 | + // killed, set pid to -1. | ||
256 | + srs_trace("SIGINT stop process pid=%d ok.", pid); | ||
257 | + pid = -1; | ||
258 | + | ||
259 | + return ret; | ||
260 | + } | ||
261 | + | ||
262 | + // then, try kill by SIGKILL. | ||
263 | + if (kill(pid, SIGKILL) < 0) { | ||
264 | + return ERROR_SYSTEM_KILL; | ||
265 | + } | ||
266 | + | ||
267 | + // wait for the process to quit. | ||
268 | + // for example, ffmpeg will gracefully quit if signal is: | ||
269 | + // 1) SIGHUP 2) SIGINT 3) SIGQUIT | ||
270 | + // other signals, directly exit(123), for example: | ||
271 | + // 9) SIGKILL 15) SIGTERM | ||
272 | + int status = 0; | ||
273 | + if (waitpid(pid, &status, 0) < 0) { | ||
274 | + return ERROR_SYSTEM_KILL; | ||
275 | + } | ||
276 | + | ||
277 | + srs_trace("SIGKILL stop process pid=%d ok.", pid); | ||
278 | + pid = -1; | ||
279 | + | ||
280 | + return ret; | ||
281 | +} | ||
282 | + | ||
225 | static SrsRusage _srs_system_rusage; | 283 | static SrsRusage _srs_system_rusage; |
226 | 284 | ||
227 | SrsRusage::SrsRusage() | 285 | SrsRusage::SrsRusage() |
@@ -422,7 +480,7 @@ void srs_update_proc_stat() | @@ -422,7 +480,7 @@ void srs_update_proc_stat() | ||
422 | // @see https://github.com/simple-rtmp-server/srs/issues/397 | 480 | // @see https://github.com/simple-rtmp-server/srs/issues/397 |
423 | static int user_hz = 0; | 481 | static int user_hz = 0; |
424 | if (user_hz <= 0) { | 482 | if (user_hz <= 0) { |
425 | - user_hz = sysconf(_SC_CLK_TCK); | 483 | + user_hz = (int)sysconf(_SC_CLK_TCK); |
426 | srs_trace("USER_HZ=%d", user_hz); | 484 | srs_trace("USER_HZ=%d", user_hz); |
427 | srs_assert(user_hz > 0); | 485 | srs_assert(user_hz > 0); |
428 | } | 486 | } |
@@ -646,12 +704,12 @@ void srs_update_disk_stat() | @@ -646,12 +704,12 @@ void srs_update_disk_stat() | ||
646 | 704 | ||
647 | if (o.pgpgin > 0 && r.pgpgin > o.pgpgin && duration_ms > 0) { | 705 | if (o.pgpgin > 0 && r.pgpgin > o.pgpgin && duration_ms > 0) { |
648 | // KBps = KB * 1000 / ms = KB/s | 706 | // KBps = KB * 1000 / ms = KB/s |
649 | - r.in_KBps = (r.pgpgin - o.pgpgin) * 1000 / duration_ms; | 707 | + r.in_KBps = (int)((r.pgpgin - o.pgpgin) * 1000 / duration_ms); |
650 | } | 708 | } |
651 | 709 | ||
652 | if (o.pgpgout > 0 && r.pgpgout > o.pgpgout && duration_ms > 0) { | 710 | if (o.pgpgout > 0 && r.pgpgout > o.pgpgout && duration_ms > 0) { |
653 | // KBps = KB * 1000 / ms = KB/s | 711 | // KBps = KB * 1000 / ms = KB/s |
654 | - r.out_KBps = (r.pgpgout - o.pgpgout) * 1000 / duration_ms; | 712 | + r.out_KBps = (int)((r.pgpgout - o.pgpgout) * 1000 / duration_ms); |
655 | } | 713 | } |
656 | } | 714 | } |
657 | 715 | ||
@@ -771,8 +829,8 @@ SrsCpuInfo* srs_get_cpuinfo() | @@ -771,8 +829,8 @@ SrsCpuInfo* srs_get_cpuinfo() | ||
771 | // initialize cpu info. | 829 | // initialize cpu info. |
772 | cpu = new SrsCpuInfo(); | 830 | cpu = new SrsCpuInfo(); |
773 | cpu->ok = true; | 831 | cpu->ok = true; |
774 | - cpu->nb_processors = sysconf(_SC_NPROCESSORS_CONF); | ||
775 | - cpu->nb_processors_online = sysconf(_SC_NPROCESSORS_ONLN); | 832 | + cpu->nb_processors = (int)sysconf(_SC_NPROCESSORS_CONF); |
833 | + cpu->nb_processors_online = (int)sysconf(_SC_NPROCESSORS_ONLN); | ||
776 | 834 | ||
777 | return cpu; | 835 | return cpu; |
778 | } | 836 | } |
@@ -80,6 +80,14 @@ extern std::string srs_path_build_timestamp(std::string template_path); | @@ -80,6 +80,14 @@ extern std::string srs_path_build_timestamp(std::string template_path); | ||
80 | extern void srs_parse_endpoint(std::string ip_port, std::string& ip, std::string& port); | 80 | extern void srs_parse_endpoint(std::string ip_port, std::string& ip, std::string& port); |
81 | extern void srs_parse_endpoint(std::string ip_port, std::string& ip, int& port); | 81 | extern void srs_parse_endpoint(std::string ip_port, std::string& ip, int& port); |
82 | 82 | ||
83 | +/** | ||
84 | + * kill the pid by SIGINT, then wait to quit, | ||
85 | + * kill the pid by SIGKILL again when exceed the timeout. | ||
86 | + * @param pid the pid to kill. ignore for -1. set to -1 when killed. | ||
87 | + * @return an int error code. | ||
88 | + */ | ||
89 | +extern int srs_kill_forced(int& pid); | ||
90 | + | ||
83 | // current process resouce usage. | 91 | // current process resouce usage. |
84 | // @see: man getrusage | 92 | // @see: man getrusage |
85 | class SrsRusage | 93 | class SrsRusage |
@@ -96,6 +96,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -96,6 +96,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
96 | #define ERROR_SYSTEM_TIME 1055 | 96 | #define ERROR_SYSTEM_TIME 1055 |
97 | #define ERROR_SYSTEM_DIR_EXISTS 1056 | 97 | #define ERROR_SYSTEM_DIR_EXISTS 1056 |
98 | #define ERROR_SYSTEM_CREATE_DIR 1057 | 98 | #define ERROR_SYSTEM_CREATE_DIR 1057 |
99 | +#define ERROR_SYSTEM_KILL 1058 | ||
99 | 100 | ||
100 | /////////////////////////////////////////////////////// | 101 | /////////////////////////////////////////////////////// |
101 | // RTMP protocol error. | 102 | // RTMP protocol error. |
-
请 注册 或 登录 后发表评论