Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
IPTV: pipe - allow to select terminate signal with forced kill (timeo…
…ut), fixes #2594
  • Loading branch information
perexg committed Oct 2, 2015
1 parent 59bc780 commit 59e62cb
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 7 deletions.
36 changes: 35 additions & 1 deletion src/input/mpegts/iptv/iptv_mux.c
Expand Up @@ -85,6 +85,20 @@ iptv_mux_url_set ( void *p, const void *v )
return 0;
}

static htsmsg_t *
iptv_muxdvr_class_kill_list ( void *o, const char *lang )
{
static const struct strtab tab[] = {
{ N_("SIGKILL"), IPTV_KILL_KILL },
{ N_("SIGTERM"), IPTV_KILL_TERM },
{ N_("SIGINT"), IPTV_KILL_INT, },
{ N_("SIGHUP"), IPTV_KILL_HUP },
{ N_("SIGUSR1"), IPTV_KILL_USR1 },
{ N_("SIGUSR2"), IPTV_KILL_USR2 },
};
return strtab2htsmsg(tab, 1, lang);
}

const idclass_t iptv_mux_class =
{
.ic_super = &mpegts_mux_class,
Expand Down Expand Up @@ -113,6 +127,7 @@ const idclass_t iptv_mux_class =
.name = N_("URL"),
.off = offsetof(iptv_mux_t, mm_iptv_url),
.set = iptv_mux_url_set,
.opts = PO_MULTILINE
},
{
.type = PT_STR,
Expand Down Expand Up @@ -143,14 +158,30 @@ const idclass_t iptv_mux_class =
.id = "iptv_respawn",
.name = N_("Respawn (pipe)"),
.off = offsetof(iptv_mux_t, mm_iptv_respawn),
.opts = PO_ADVANCED
},
{
.type = PT_INT,
.id = "iptv_kill",
.name = N_("Kill signal (pipe)"),
.off = offsetof(iptv_mux_t, mm_iptv_kill),
.list = iptv_muxdvr_class_kill_list,
.opts = PO_ADVANCED
},
{
.type = PT_INT,
.id = "iptv_kill_timeout",
.name = N_("Kill timeout (pipe/secs)"),
.off = offsetof(iptv_mux_t, mm_iptv_kill_timeout),
.opts = PO_ADVANCED,
.def.i = 5
},
{
.type = PT_STR,
.id = "iptv_env",
.name = N_("Environment (pipe)"),
.off = offsetof(iptv_mux_t, mm_iptv_env),
.opts = PO_ADVANCED,
.opts = PO_ADVANCED | PO_MULTILINE
},
{}
}
Expand Down Expand Up @@ -226,6 +257,9 @@ iptv_mux_create0 ( iptv_network_t *in, const char *uuid, htsmsg_t *conf )
im->mm_config_save = iptv_mux_config_save;
im->mm_delete = iptv_mux_delete;

if (!im->mm_iptv_kill_timeout)
im->mm_iptv_kill_timeout = 5;

/* Create Instance */
(void)mpegts_mux_instance_create(mpegts_mux_instance, NULL,
(mpegts_input_t*)iptv_input,
Expand Down
17 changes: 15 additions & 2 deletions src/input/mpegts/iptv/iptv_pipe.c
Expand Up @@ -76,13 +76,26 @@ iptv_pipe_start ( iptv_mux_t *im, const char *raw, const url_t *url )
return -1;
}

static int
iptv_pipe_kill_sig(iptv_mux_t *im)
{
switch (im->mm_iptv_kill) {
case IPTV_KILL_TERM: return SIGTERM;
case IPTV_KILL_INT: return SIGINT;
case IPTV_KILL_HUP: return SIGHUP;
case IPTV_KILL_USR1: return SIGUSR1;
case IPTV_KILL_USR2: return SIGUSR2;
}
return SIGKILL;
}

static void
iptv_pipe_stop
( iptv_mux_t *im )
{
int rd = im->mm_iptv_fd;
pid_t pid = (intptr_t)im->im_data;
spawn_kill(pid, SIGKILL);
spawn_kill(pid, iptv_pipe_kill_sig(im), im->mm_iptv_kill_timeout);
if (rd > 0)
close(rd);
im->mm_iptv_fd = -1;
Expand All @@ -107,7 +120,7 @@ iptv_pipe_read ( iptv_mux_t *im )
if (r <= 0) {
close(rd);
pid = (intptr_t)im->im_data;
spawn_kill(pid, SIGKILL);
spawn_kill(pid, iptv_pipe_kill_sig(im), im->mm_iptv_kill_timeout);
im->mm_iptv_fd = -1;
im->im_data = NULL;
if (dispatch_clock < im->mm_iptv_respawn_last + 2) {
Expand Down
9 changes: 9 additions & 0 deletions src/input/mpegts/iptv/iptv_private.h
Expand Up @@ -29,6 +29,13 @@
#define IPTV_PKTS 32
#define IPTV_PKT_PAYLOAD 1472

#define IPTV_KILL_KILL 0
#define IPTV_KILL_TERM 1
#define IPTV_KILL_INT 2
#define IPTV_KILL_HUP 3
#define IPTV_KILL_USR1 4
#define IPTV_KILL_USR2 5

extern pthread_mutex_t iptv_lock;

typedef struct iptv_input iptv_input_t;
Expand Down Expand Up @@ -96,6 +103,8 @@ struct iptv_mux

int mm_iptv_respawn;
time_t mm_iptv_respawn_last;
int mm_iptv_kill;
int mm_iptv_kill_timeout;
char *mm_iptv_env;

uint32_t mm_iptv_rtp_seq;
Expand Down
3 changes: 2 additions & 1 deletion src/main.c
Expand Up @@ -486,7 +486,7 @@ show_usage
/**
*
*/
void
time_t
dispatch_clock_update(struct timespec *ts)
{
struct timespec ts1;
Expand All @@ -499,6 +499,7 @@ dispatch_clock_update(struct timespec *ts)
dispatch_clock = ts->tv_sec;
comet_flush(); /* Flush idle comet mailboxes */
}
return dispatch_clock;
}

/**
Expand Down
15 changes: 14 additions & 1 deletion src/spawn.c
Expand Up @@ -58,6 +58,7 @@ typedef struct spawn {
LIST_ENTRY(spawn) link;
pid_t pid;
const char *name;
time_t killed;
} spawn_t;

static void spawn_reaper(void);
Expand Down Expand Up @@ -287,6 +288,7 @@ static void
spawn_reaper(void)
{
int r;
spawn_t *s;

do {
r = spawn_reap(-1, NULL, 0);
Expand All @@ -295,13 +297,22 @@ spawn_reaper(void)
if (r <= 0)
break;
} while (1);

/* forced kill for expired PIDs */
pthread_mutex_lock(&spawn_mutex);
LIST_FOREACH(s, &spawns, link)
if (s->killed && s->killed < dispatch_clock) {
/* kill the whole process group */
kill(-(s->pid), SIGKILL);
}
pthread_mutex_unlock(&spawn_mutex);
}

/**
* Kill the pid (only if waiting)
*/
int
spawn_kill(pid_t pid, int sig)
spawn_kill(pid_t pid, int sig, int timeout)
{
int r = -ESRCH;
spawn_t *s;
Expand All @@ -314,6 +325,8 @@ spawn_kill(pid_t pid, int sig)
if(s->pid == pid)
break;
if (s) {
if (!s->killed)
s->killed = dispatch_clock_update(NULL) + MAX(MIN(5, timeout), 3600);
/* kill the whole process group */
r = kill(-pid, sig);
if (r < 0)
Expand Down
2 changes: 1 addition & 1 deletion src/spawn.h
Expand Up @@ -36,7 +36,7 @@ int spawnv(const char *prog, char *argv[], pid_t *pid, int redir_stdout, int red

int spawn_reap(pid_t pid, char *stxt, size_t stxtlen);

int spawn_kill(pid_t pid, int sig);
int spawn_kill(pid_t pid, int sig, int timeout);

void spawn_init(void);

Expand Down
2 changes: 1 addition & 1 deletion src/tvhlog.h
Expand Up @@ -129,6 +129,6 @@ static inline void tvhtrace_no_warnings(const char *fmt, ...) { (void)fmt; }
#define tvhnotice(...) tvhlog(LOG_NOTICE, ##__VA_ARGS__)
#define tvherror(...) tvhlog(LOG_ERR, ##__VA_ARGS__)

void dispatch_clock_update(struct timespec *ts);
time_t dispatch_clock_update(struct timespec *ts);

#endif /* __TVH_LOGGING_H__ */

0 comments on commit 59e62cb

Please sign in to comment.