diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c index ef2caaad68..4ec689b6ec 100644 --- a/apps/app_mixmonitor.c +++ b/apps/app_mixmonitor.c @@ -521,6 +521,7 @@ struct mixmonitor_ds { struct ast_filestream *fs_write; struct ast_audiohook *audiohook; + char *datastore_id; unsigned int samp_rate; char *filename; @@ -570,6 +571,7 @@ static void mixmonitor_ds_destroy(void *data) mixmonitor_ds->destruction_ok = 1; ast_free(mixmonitor_ds->filename); ast_free(mixmonitor_ds->beep_id); + ast_free(mixmonitor_ds->datastore_id); ast_cond_signal(&mixmonitor_ds->destruction_condition); ast_mutex_unlock(&mixmonitor_ds->lock); } @@ -848,6 +850,9 @@ static int mixmonitor_autochan_is_bridged(struct ast_autochan *autochan) return is_bridged; } +/* Forward declaration */ +static void mixmonitor_ds_remove_and_free(struct ast_channel *chan, const char *datastore_id); + static void *mixmonitor_thread(void *obj) { struct mixmonitor *mixmonitor = obj; @@ -875,8 +880,6 @@ static void *mixmonitor_thread(void *obj) ast_callid_threadassoc_add(mixmonitor->callid); } - ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name); - fs = &mixmonitor->mixmonitor_ds->fs; fs_read = &mixmonitor->mixmonitor_ds->fs_read; fs_write = &mixmonitor->mixmonitor_ds->fs_write; @@ -888,6 +891,35 @@ static void *mixmonitor_thread(void *obj) format_slin = ast_format_cache_get_slin_by_rate(mixmonitor->mixmonitor_ds->samp_rate); + if (errflag) { + /* Tear everything down and exit. */ + mixmonitor_ds_close_fs(mixmonitor->mixmonitor_ds); + mixmonitor->mixmonitor_ds->audiohook = NULL; + + ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock); + + ast_autochan_channel_lock(mixmonitor->autochan); + ast_audiohook_remove(mixmonitor->autochan->chan, &mixmonitor->audiohook); + + mixmonitor_ds_remove_and_free(mixmonitor->autochan->chan, mixmonitor->mixmonitor_ds->datastore_id); + ast_autochan_channel_unlock(mixmonitor->autochan); + ast_autochan_destroy(mixmonitor->autochan); + + ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock); + if (!mixmonitor->mixmonitor_ds->destruction_ok) { + ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock); + } + ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock); + + ast_audiohook_destroy(&mixmonitor->audiohook); + mixmonitor_free(mixmonitor); + + ast_module_unref(ast_module_info->self); + return NULL; + } + + ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name); + ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock); if (mixmonitor->skip_seconds > 0.0) { @@ -1042,6 +1074,7 @@ frame_cleanup: if (!mixmonitor->mixmonitor_ds->destruction_ok) { ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock); } + ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock); /* Free the translate paths */ @@ -1316,7 +1349,7 @@ static int launch_monitor_thread(struct ast_channel *chan, const char *filename, return -1; } - ast_free(datastore_id); + mixmonitor->mixmonitor_ds->datastore_id = datastore_id; /* Steal the reference */ /* reference be released at mixmonitor destruction */ mixmonitor->callid = ast_read_threadstorage_callid();