mirror of
https://github.com/asterisk/asterisk.git
synced 2025-11-16 14:58:25 +00:00
app_mixmonitor: Fix crashes caused by unloading app_mixmonitor
Unloading app_mixmonitor while active mixmonitors were running would cause a segfault. This patch fixes that by making it impossible to unload app_mixmonitor while mixmonitors are active. Review: https://reviewboard.asterisk.org/r/2624/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@391778 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
@@ -381,6 +381,8 @@ static void *mixmonitor_thread(void *obj)
|
|||||||
|
|
||||||
ast_verb(2, "End MixMonitor Recording %s\n", mixmonitor->name);
|
ast_verb(2, "End MixMonitor Recording %s\n", mixmonitor->name);
|
||||||
mixmonitor_free(mixmonitor);
|
mixmonitor_free(mixmonitor);
|
||||||
|
|
||||||
|
ast_module_unref(ast_module_info->self);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +416,7 @@ static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void launch_monitor_thread(struct ast_channel *chan, const char *filename, unsigned int flags,
|
static int launch_monitor_thread(struct ast_channel *chan, const char *filename, unsigned int flags,
|
||||||
int readvol, int writevol, const char *post_process)
|
int readvol, int writevol, const char *post_process)
|
||||||
{
|
{
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
@@ -442,26 +444,26 @@ static void launch_monitor_thread(struct ast_channel *chan, const char *filename
|
|||||||
|
|
||||||
/* Pre-allocate mixmonitor structure and spy */
|
/* Pre-allocate mixmonitor structure and spy */
|
||||||
if (!(mixmonitor = ast_calloc(1, len))) {
|
if (!(mixmonitor = ast_calloc(1, len))) {
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Setup the actual spy before creating our thread */
|
/* Setup the actual spy before creating our thread */
|
||||||
if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) {
|
if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) {
|
||||||
mixmonitor_free(mixmonitor);
|
mixmonitor_free(mixmonitor);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy over flags and channel name */
|
/* Copy over flags and channel name */
|
||||||
mixmonitor->flags = flags;
|
mixmonitor->flags = flags;
|
||||||
if (!(mixmonitor->autochan = ast_autochan_setup(chan))) {
|
if (!(mixmonitor->autochan = ast_autochan_setup(chan))) {
|
||||||
mixmonitor_free(mixmonitor);
|
mixmonitor_free(mixmonitor);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setup_mixmonitor_ds(mixmonitor, chan)) {
|
if (setup_mixmonitor_ds(mixmonitor, chan)) {
|
||||||
ast_autochan_destroy(mixmonitor->autochan);
|
ast_autochan_destroy(mixmonitor->autochan);
|
||||||
mixmonitor_free(mixmonitor);
|
mixmonitor_free(mixmonitor);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
|
mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
|
||||||
strcpy(mixmonitor->name, chan->name);
|
strcpy(mixmonitor->name, chan->name);
|
||||||
@@ -485,10 +487,10 @@ static void launch_monitor_thread(struct ast_channel *chan, const char *filename
|
|||||||
mixmonitor_spy_type, chan->name);
|
mixmonitor_spy_type, chan->name);
|
||||||
ast_audiohook_destroy(&mixmonitor->audiohook);
|
ast_audiohook_destroy(&mixmonitor->audiohook);
|
||||||
mixmonitor_free(mixmonitor);
|
mixmonitor_free(mixmonitor);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor);
|
return ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mixmonitor_exec(struct ast_channel *chan, const char *data)
|
static int mixmonitor_exec(struct ast_channel *chan, const char *data)
|
||||||
@@ -567,7 +569,12 @@ static int mixmonitor_exec(struct ast_channel *chan, const char *data)
|
|||||||
ast_mkdir(tmp, 0777);
|
ast_mkdir(tmp, 0777);
|
||||||
|
|
||||||
pbx_builtin_setvar_helper(chan, "MIXMONITOR_FILENAME", args.filename);
|
pbx_builtin_setvar_helper(chan, "MIXMONITOR_FILENAME", args.filename);
|
||||||
launch_monitor_thread(chan, args.filename, flags.flags, readvol, writevol, args.post_process);
|
|
||||||
|
/* If launch_monitor_thread works, the module reference must not be released until it is finished. */
|
||||||
|
ast_module_ref(ast_module_info->self);
|
||||||
|
if (launch_monitor_thread(chan, args.filename, flags.flags, readvol, writevol, args.post_process)) {
|
||||||
|
ast_module_unref(ast_module_info->self);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user