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. |
-
请 注册 或 登录 后发表评论