diff --git a/trunk/src/app/srs_app_ffmpeg.cpp b/trunk/src/app/srs_app_ffmpeg.cpp index 373a1a004..7da9b3c50 100644 --- a/trunk/src/app/srs_app_ffmpeg.cpp +++ b/trunk/src/app/srs_app_ffmpeg.cpp @@ -35,6 +35,7 @@ using namespace std; #include #include #include +#include #ifdef SRS_AUTO_FFMPEG_STUB @@ -509,24 +510,14 @@ void SrsFFMPEG::stop() // when rewind, upstream will stop publish(unpublish), // unpublish event will stop all ffmpeg encoders, // then publish will start all ffmpeg encoders. - if (pid > 0) { - if (kill(pid, SIGKILL) < 0) { - srs_warn("kill the encoder failed, ignored. pid=%d", pid); - } - - // wait for the ffmpeg to quit. - // ffmpeg will gracefully quit if signal is: - // 1) SIGHUP 2) SIGINT 3) SIGQUIT - // other signals, directly exit(123), for example: - // 9) SIGKILL 15) SIGTERM - int status = 0; - if (waitpid(pid, &status, 0) < 0) { - srs_warn("wait the encoder quit failed, ignored. pid=%d", pid); - } - - srs_trace("stop the encoder success. pid=%d", pid); - pid = -1; + int ret = srs_kill_forced(pid); + if (ret != ERROR_SUCCESS) { + srs_warn("ignore kill the encoder failed, pid=%d. ret=%d", pid, ret); + return; } + + // terminated, set started to false to stop the cycle. + started = false; } #endif diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index 31e4681a7..ba64e8723 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include #include #include +#include #ifdef SRS_OSX #include @@ -222,6 +223,63 @@ void srs_parse_endpoint(string ip_port, string& ip, int& port) port = ::atoi(the_port.c_str()); } +#define SRS_PROCESS_QUIT_TIMEOUT_MS 1000 +int srs_kill_forced(int& pid) +{ + int ret = ERROR_SUCCESS; + + if (pid <= 0) { + return ret; + } + + // first, try kill by SIGINT. + if (kill(pid, SIGINT) < 0) { + return ERROR_SYSTEM_KILL; + } + + // wait to quit. + srs_trace("send SIGINT to pid=%d", pid); + for (int i = 0; i < SRS_PROCESS_QUIT_TIMEOUT_MS / 10; i++) { + int status = 0; + pid_t qpid = -1; + if ((qpid = waitpid(pid, &status, WNOHANG)) < 0) { + return ERROR_SYSTEM_KILL; + } + + // 0 is not quit yet. + if (qpid == 0) { + st_usleep(10 * 1000); + continue; + } + + // killed, set pid to -1. + srs_trace("SIGINT stop process pid=%d ok.", pid); + pid = -1; + + return ret; + } + + // then, try kill by SIGKILL. + if (kill(pid, SIGKILL) < 0) { + return ERROR_SYSTEM_KILL; + } + + // wait for the process to quit. + // for example, ffmpeg will gracefully quit if signal is: + // 1) SIGHUP 2) SIGINT 3) SIGQUIT + // other signals, directly exit(123), for example: + // 9) SIGKILL 15) SIGTERM + int status = 0; + if (waitpid(pid, &status, 0) < 0) { + return ERROR_SYSTEM_KILL; + } + + srs_trace("SIGKILL stop process pid=%d ok.", pid); + pid = -1; + + return ret; +} + static SrsRusage _srs_system_rusage; SrsRusage::SrsRusage() @@ -422,7 +480,7 @@ void srs_update_proc_stat() // @see https://github.com/simple-rtmp-server/srs/issues/397 static int user_hz = 0; if (user_hz <= 0) { - user_hz = sysconf(_SC_CLK_TCK); + user_hz = (int)sysconf(_SC_CLK_TCK); srs_trace("USER_HZ=%d", user_hz); srs_assert(user_hz > 0); } @@ -646,12 +704,12 @@ void srs_update_disk_stat() if (o.pgpgin > 0 && r.pgpgin > o.pgpgin && duration_ms > 0) { // KBps = KB * 1000 / ms = KB/s - r.in_KBps = (r.pgpgin - o.pgpgin) * 1000 / duration_ms; + r.in_KBps = (int)((r.pgpgin - o.pgpgin) * 1000 / duration_ms); } if (o.pgpgout > 0 && r.pgpgout > o.pgpgout && duration_ms > 0) { // KBps = KB * 1000 / ms = KB/s - r.out_KBps = (r.pgpgout - o.pgpgout) * 1000 / duration_ms; + r.out_KBps = (int)((r.pgpgout - o.pgpgout) * 1000 / duration_ms); } } @@ -771,8 +829,8 @@ SrsCpuInfo* srs_get_cpuinfo() // initialize cpu info. cpu = new SrsCpuInfo(); cpu->ok = true; - cpu->nb_processors = sysconf(_SC_NPROCESSORS_CONF); - cpu->nb_processors_online = sysconf(_SC_NPROCESSORS_ONLN); + cpu->nb_processors = (int)sysconf(_SC_NPROCESSORS_CONF); + cpu->nb_processors_online = (int)sysconf(_SC_NPROCESSORS_ONLN); return cpu; } diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index e86519db0..cd95b9781 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -80,6 +80,14 @@ extern std::string srs_path_build_timestamp(std::string template_path); extern void srs_parse_endpoint(std::string ip_port, std::string& ip, std::string& port); extern void srs_parse_endpoint(std::string ip_port, std::string& ip, int& port); +/** + * kill the pid by SIGINT, then wait to quit, + * kill the pid by SIGKILL again when exceed the timeout. + * @param pid the pid to kill. ignore for -1. set to -1 when killed. + * @return an int error code. + */ +extern int srs_kill_forced(int& pid); + // current process resouce usage. // @see: man getrusage class SrsRusage diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index dec0f3f72..5f43da1d0 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -96,6 +96,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_SYSTEM_TIME 1055 #define ERROR_SYSTEM_DIR_EXISTS 1056 #define ERROR_SYSTEM_CREATE_DIR 1057 +#define ERROR_SYSTEM_KILL 1058 /////////////////////////////////////////////////////// // RTMP protocol error.