mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
for #374, use SIGINT then SIGKILL to try to kill FFMPEG gracefullly.
This commit is contained in:
parent
5caafadd45
commit
db57a519a9
4 changed files with 80 additions and 22 deletions
|
@ -35,6 +35,7 @@ using namespace std;
|
||||||
#include <srs_kernel_error.hpp>
|
#include <srs_kernel_error.hpp>
|
||||||
#include <srs_kernel_log.hpp>
|
#include <srs_kernel_log.hpp>
|
||||||
#include <srs_app_config.hpp>
|
#include <srs_app_config.hpp>
|
||||||
|
#include <srs_app_utility.hpp>
|
||||||
|
|
||||||
#ifdef SRS_AUTO_FFMPEG_STUB
|
#ifdef SRS_AUTO_FFMPEG_STUB
|
||||||
|
|
||||||
|
@ -509,24 +510,14 @@ void SrsFFMPEG::stop()
|
||||||
// when rewind, upstream will stop publish(unpublish),
|
// when rewind, upstream will stop publish(unpublish),
|
||||||
// unpublish event will stop all ffmpeg encoders,
|
// unpublish event will stop all ffmpeg encoders,
|
||||||
// then publish will start all ffmpeg encoders.
|
// then publish will start all ffmpeg encoders.
|
||||||
if (pid > 0) {
|
int ret = srs_kill_forced(pid);
|
||||||
if (kill(pid, SIGKILL) < 0) {
|
if (ret != ERROR_SUCCESS) {
|
||||||
srs_warn("kill the encoder failed, ignored. pid=%d", pid);
|
srs_warn("ignore kill the encoder failed, pid=%d. ret=%d", pid, ret);
|
||||||
}
|
return;
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// terminated, set started to false to stop the cycle.
|
||||||
|
started = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
#ifdef SRS_OSX
|
#ifdef SRS_OSX
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
@ -222,6 +223,63 @@ void srs_parse_endpoint(string ip_port, string& ip, int& port)
|
||||||
port = ::atoi(the_port.c_str());
|
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;
|
static SrsRusage _srs_system_rusage;
|
||||||
|
|
||||||
SrsRusage::SrsRusage()
|
SrsRusage::SrsRusage()
|
||||||
|
@ -422,7 +480,7 @@ void srs_update_proc_stat()
|
||||||
// @see https://github.com/simple-rtmp-server/srs/issues/397
|
// @see https://github.com/simple-rtmp-server/srs/issues/397
|
||||||
static int user_hz = 0;
|
static int user_hz = 0;
|
||||||
if (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_trace("USER_HZ=%d", user_hz);
|
||||||
srs_assert(user_hz > 0);
|
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) {
|
if (o.pgpgin > 0 && r.pgpgin > o.pgpgin && duration_ms > 0) {
|
||||||
// KBps = KB * 1000 / ms = KB/s
|
// 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) {
|
if (o.pgpgout > 0 && r.pgpgout > o.pgpgout && duration_ms > 0) {
|
||||||
// KBps = KB * 1000 / ms = KB/s
|
// 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.
|
// initialize cpu info.
|
||||||
cpu = new SrsCpuInfo();
|
cpu = new SrsCpuInfo();
|
||||||
cpu->ok = true;
|
cpu->ok = true;
|
||||||
cpu->nb_processors = sysconf(_SC_NPROCESSORS_CONF);
|
cpu->nb_processors = (int)sysconf(_SC_NPROCESSORS_CONF);
|
||||||
cpu->nb_processors_online = sysconf(_SC_NPROCESSORS_ONLN);
|
cpu->nb_processors_online = (int)sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
|
|
||||||
return cpu;
|
return cpu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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, std::string& port);
|
||||||
extern void srs_parse_endpoint(std::string ip_port, std::string& ip, int& 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.
|
// current process resouce usage.
|
||||||
// @see: man getrusage
|
// @see: man getrusage
|
||||||
class SrsRusage
|
class SrsRusage
|
||||||
|
|
|
@ -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_TIME 1055
|
||||||
#define ERROR_SYSTEM_DIR_EXISTS 1056
|
#define ERROR_SYSTEM_DIR_EXISTS 1056
|
||||||
#define ERROR_SYSTEM_CREATE_DIR 1057
|
#define ERROR_SYSTEM_CREATE_DIR 1057
|
||||||
|
#define ERROR_SYSTEM_KILL 1058
|
||||||
|
|
||||||
///////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////
|
||||||
// RTMP protocol error.
|
// RTMP protocol error.
|
||||||
|
|
Loading…
Reference in a new issue