[Asterisk-code-review] res musiconhold: Add 'kill escalation delay option to classes (asterisk[13])
George Joseph
asteriskteam at digium.com
Tue Jul 11 08:03:22 CDT 2017
George Joseph has uploaded this change for review. ( https://gerrit.asterisk.org/5984
Change subject: res_musiconhold: Add 'kill_escalation_delay option to classes
......................................................................
res_musiconhold: Add 'kill_escalation_delay option to classes
By default, when res_musiconhold reloads or unloads, it sends a HUP
signal to the custom application's process group, waits 100ms, then
sends a TERM signal, waits 100ms, then finally sends a KILL signal.
An application which is interacting with an external device and/or
spawns children of its own may not be able to exit cleanly in the
default times, expecially if sent a KILL signal.
* To allow extra time, the 'kill_escalation_delay' option was added
to the class definition which sets the number of milliseconds to
wait before escalating kill signals. The default remains 100ms.
* The killpg (kill process group) calls were replaced with simple
kills to allow the child process to decide how to terminate any
children rather than us sending signals to all descendants
directly.
Change-Id: Iff70a1a9405685a9021a68416830c0db5158603b
---
M CHANGES
M configs/samples/musiconhold.conf.sample
M res/res_musiconhold.c
3 files changed, 72 insertions(+), 46 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/84/5984/1
diff --git a/CHANGES b/CHANGES
index c3a2d0a..e2a02f4 100644
--- a/CHANGES
+++ b/CHANGES
@@ -9,6 +9,21 @@
==============================================================================
------------------------------------------------------------------------------
+--- Functionality changes from Asterisk 13.17.0 to Asterisk 13.18.0 ----------
+------------------------------------------------------------------------------
+
+res_musiconhold
+------------------
+ * By default, when res_musiconhold reloads or unloads, it sends a HUP signal
+ to custom applications, waits 100ms, then sends a TERM signal, waits 100ms,
+ then finally sends a KILL signal. An application which is interacting with
+ an external device and/or spawns children of its own may not be able to
+ exit cleanly in the default times, expecially if sent a KILL signal. To
+ allow extra time, the 'kill_escalation_delay' option was added to the
+ class definition which sets the number of milliseconds to wait before
+ escalating kill signals.
+
+------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.16.0 to Asterisk 13.17.0 ----------
------------------------------------------------------------------------------
diff --git a/configs/samples/musiconhold.conf.sample b/configs/samples/musiconhold.conf.sample
index 8b2202d..8345a69 100644
--- a/configs/samples/musiconhold.conf.sample
+++ b/configs/samples/musiconhold.conf.sample
@@ -91,3 +91,17 @@
;mode=custom
;directory=/var/lib/asterisk/mohmp3
;application=/site/sw/bin/madplay -Q -o raw:- --mono -R 8000 -a -12
+
+; By default, when res_musiconhold reloads or unloads, it sends a HUP signal
+; to custom applications, waits 100ms, then sends a TERM signal, waits 100ms,
+; then finally sends a KILL signal. An application which is interacting with
+; an external device and/or spawns children of its own may not be able to
+; exit cleanly in the default times, expecially if sent a KILL signal. To
+; allow extra time, set 'kill_escalation_delay' to the number of milliseconds
+; to wait before escalating kill signals.
+;[sox_from_device]
+;mode=custom
+;directory=/var/lib/asterisk/mohmp3
+;application=/usr/bin/sox -q -t alsa -c 2 -r 48000 hw:1 -c 1 -r 8000 -t raw -s -
+; Wait 500ms before escalating kill signals
+;kill_escalation_delay=500
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index c52c964..11489e4 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -178,6 +178,8 @@
int pid;
time_t start;
pthread_t thread;
+ /*! Millisecond delay between kill attempts */
+ size_t killdelay;
/*! Source of audio */
int srcfd;
/*! Generic timer */
@@ -678,6 +680,36 @@
return fds[0];
}
+static void killpid(int pid, size_t delay)
+{
+ if (kill(pid, SIGHUP) < 0) {
+ if (errno == ESRCH) {
+ return;
+ }
+ ast_log(LOG_WARNING, "Unable to send a SIGHUP to MOH process '%d'?!!: %s\n", pid, strerror(errno));
+ } else {
+ ast_debug(1, "Sent HUP to pid %d\n", pid);
+ }
+ usleep(delay);
+ if (kill(pid, SIGTERM) < 0) {
+ if (errno == ESRCH) {
+ return;
+ }
+ ast_log(LOG_WARNING, "Unable to terminate MOH process '%d'?!!: %s\n", pid, strerror(errno));
+ } else {
+ ast_debug(1, "Sent TERM to pid %d\n", pid);
+ }
+ usleep(delay);
+ if (kill(pid, SIGKILL) < 0) {
+ if (errno == ESRCH) {
+ return;
+ }
+ ast_log(LOG_WARNING, "Unable to kill MOH process '%d'?!!: %s\n", pid, strerror(errno));
+ } else {
+ ast_debug(1, "Sent KILL to pid %d\n", pid);
+ }
+}
+
static void *monmp3thread(void *data)
{
#define MOH_MS_INTERVAL 100
@@ -753,28 +785,7 @@
class->srcfd = -1;
pthread_testcancel();
if (class->pid > 1) {
- do {
- if (killpg(class->pid, SIGHUP) < 0) {
- if (errno == ESRCH) {
- break;
- }
- ast_log(LOG_WARNING, "Unable to send a SIGHUP to MOH process?!!: %s\n", strerror(errno));
- }
- usleep(100000);
- if (killpg(class->pid, SIGTERM) < 0) {
- if (errno == ESRCH) {
- break;
- }
- ast_log(LOG_WARNING, "Unable to terminate MOH process?!!: %s\n", strerror(errno));
- }
- usleep(100000);
- if (killpg(class->pid, SIGKILL) < 0) {
- if (errno == ESRCH) {
- break;
- }
- ast_log(LOG_WARNING, "Unable to kill MOH process?!!: %s\n", strerror(errno));
- }
- } while (0);
+ killpid(class->pid, class->killdelay);
class->pid = 0;
}
} else {
@@ -1328,6 +1339,7 @@
)) {
class->format = ao2_bump(ast_format_slin);
class->srcfd = -1;
+ class->killdelay = 100000;
}
return class;
@@ -1605,31 +1617,8 @@
ast_debug(1, "killing %d!\n", class->pid);
stime = time(NULL) + 2;
- pid = class->pid;
+ killpid(class->pid, class->killdelay);
class->pid = 0;
-
- /* Back when this was just mpg123, SIGKILL was fine. Now we need
- * to give the process a reason and time enough to kill off its
- * children. */
- do {
- if (killpg(pid, SIGHUP) < 0) {
- ast_log(LOG_WARNING, "Unable to send a SIGHUP to MOH process?!!: %s\n", strerror(errno));
- }
- usleep(100000);
- if (killpg(pid, SIGTERM) < 0) {
- if (errno == ESRCH) {
- break;
- }
- ast_log(LOG_WARNING, "Unable to terminate MOH process?!!: %s\n", strerror(errno));
- }
- usleep(100000);
- if (killpg(pid, SIGKILL) < 0) {
- if (errno == ESRCH) {
- break;
- }
- ast_log(LOG_WARNING, "Unable to kill MOH process?!!: %s\n", strerror(errno));
- }
- } while (0);
while ((ast_wait_for_input(class->srcfd, 100) > 0) &&
(bytes = read(class->srcfd, buff, 8192)) && time(NULL) < stime) {
@@ -1765,6 +1754,13 @@
ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", var->value);
class->format = ao2_bump(ast_format_slin);
}
+ } else if (!strcasecmp(var->name, "kill_escalation_delay")) {
+ if (sscanf(var->value, "%zu", &class->killdelay) == 1) {
+ class->killdelay *= 1000;
+ } else {
+ ast_log(LOG_WARNING, "kill_escalation_delay '%s' is invalid. Setting to 100ms\n", var->value);
+ class->killdelay = 100000;
+ }
}
}
@@ -1899,6 +1895,7 @@
ast_cli(a->fd, "\tDirectory: %s\n", S_OR(class->dir, "<none>"));
if (ast_test_flag(class, MOH_CUSTOM)) {
ast_cli(a->fd, "\tApplication: %s\n", S_OR(class->args, "<none>"));
+ ast_cli(a->fd, "\tKill Escalation Delay: %zu ms\n", class->killdelay / 1000);
}
if (strcasecmp(class->mode, "files")) {
ast_cli(a->fd, "\tFormat: %s\n", ast_format_get_name(class->format));
--
To view, visit https://gerrit.asterisk.org/5984
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: 13
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iff70a1a9405685a9021a68416830c0db5158603b
Gerrit-Change-Number: 5984
Gerrit-PatchSet: 1
Gerrit-Owner: George Joseph <gjoseph at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20170711/39ddebb6/attachment.html>
More information about the asterisk-code-review
mailing list