FS-8811 #resolve [FS 1.7 crashes intermittently]

This commit is contained in:
Anthony Minessale 2016-03-04 16:56:55 -06:00
parent 89c2abaff2
commit 550029b80e
14 changed files with 75 additions and 68 deletions

View File

@ -390,6 +390,7 @@ struct switch_file_handle {
char *stream_name;
char *modname;
switch_mm_t mm;
switch_mutex_t *flag_mutex;
};
/*! \brief Abstract interface to an asr module */

View File

@ -635,17 +635,17 @@ SWITCH_DECLARE(unsigned char) switch_char_to_rfc2833(char key);
\param obj the object to set the flags on
\param flag the or'd list of flags to set
*/
#define switch_set_flag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
switch_mutex_lock(obj->flag_mutex);\
#define switch_set_flag_locked(obj, flag) assert((obj)->flag_mutex != NULL); \
switch_mutex_lock((obj)->flag_mutex); \
(obj)->flags |= (flag);\
switch_mutex_unlock(obj->flag_mutex);
switch_mutex_unlock((obj)->flag_mutex);
/*!
\brief Clear a flag on an arbitrary object
\param obj the object to test
\param flag the or'd list of flags to clear
*/
#define switch_clear_flag_locked(obj, flag) switch_mutex_lock(obj->flag_mutex); (obj)->flags &= ~(flag); switch_mutex_unlock(obj->flag_mutex);
#define switch_clear_flag_locked(obj, flag) switch_mutex_lock((obj)->flag_mutex); (obj)->flags &= ~(flag); switch_mutex_unlock((obj)->flag_mutex);
/*!
\brief Clear a flag on an arbitrary object while locked

View File

@ -2810,7 +2810,6 @@ SWITCH_STANDARD_APP(playback_function)
status = switch_ivr_play_file(session, &fh, file, &args);
switch_assert(!(fh.flags & SWITCH_FILE_OPEN));
switch (status) {
case SWITCH_STATUS_SUCCESS:
case SWITCH_STATUS_BREAK:
@ -4782,9 +4781,9 @@ static switch_status_t next_file(switch_file_handle_t *handle)
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
switch_set_flag_locked(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
}
@ -5003,9 +5002,9 @@ static switch_status_t file_url_file_open(switch_file_handle_t *handle, const ch
handle->max_samples = 0;
if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
switch_set_flag_locked(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
}
}
return status;

View File

@ -2986,9 +2986,9 @@ static switch_status_t file_open(switch_file_handle_t *handle, const char *path,
handle->flags |= SWITCH_FILE_NOMUX;
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
switch_set_flag_locked(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
}
return SWITCH_STATUS_SUCCESS;

View File

@ -1713,9 +1713,9 @@ static switch_status_t http_cache_file_open(switch_file_handle_t *handle, const
handle->flags |= SWITCH_FILE_NOMUX;
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
switch_set_flag_locked(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
}
return status;

View File

@ -935,9 +935,9 @@ static switch_status_t control_playback(switch_core_session_t *session, void *in
if (dtmf->digit == *cc->profile->pause_key) {
if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
switch_clear_flag(fh, SWITCH_FILE_PAUSE);
switch_clear_flag_locked(fh, SWITCH_FILE_PAUSE);
} else {
switch_set_flag(fh, SWITCH_FILE_PAUSE);
switch_set_flag_locked(fh, SWITCH_FILE_PAUSE);
}
return SWITCH_STATUS_SUCCESS;
}

View File

@ -626,9 +626,9 @@ static switch_status_t next_file(switch_file_handle_t *handle)
handle->interval = context->fh.interval;
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
switch_set_flag_locked(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
}
return SWITCH_STATUS_SUCCESS;
@ -878,13 +878,13 @@ static switch_status_t fileman_file_open(switch_file_handle_t *handle, const cha
handle->interval = context->fh.interval;
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
switch_set_flag_locked(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
}
if (handle->params && switch_true(switch_event_get_header(handle->params, "pause"))) {
switch_set_flag(handle, SWITCH_FILE_PAUSE);
switch_set_flag_locked(handle, SWITCH_FILE_PAUSE);
}
if (handle->seekable && start_offset_ms) {
@ -1071,7 +1071,7 @@ static switch_status_t fileman_file_read(switch_file_handle_t *handle, void *dat
if (switch_test_flag(fh, SWITCH_FILE_SEEK)) {
/* file position has changed flush the buffer */
switch_buffer_zero(fh->audio_buffer);
switch_clear_flag(fh, SWITCH_FILE_SEEK);
switch_clear_flag_locked(fh, SWITCH_FILE_SEEK);
}
/* generate speed frames */
@ -1216,15 +1216,15 @@ static switch_status_t fileman_process_cmd(const char *cmd, switch_file_handle_t
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(cmd, "pause")) {
switch_set_flag(fhp, SWITCH_FILE_PAUSE);
switch_set_flag_locked(fhp, SWITCH_FILE_PAUSE);
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(cmd, "resume")) {
switch_clear_flag(fhp, SWITCH_FILE_PAUSE);
switch_clear_flag_locked(fhp, SWITCH_FILE_PAUSE);
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(cmd, "stop")) {
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(context->uuid), SWITCH_LOG_DEBUG, "Stopping file\n");
context->done = 1;
switch_set_flag(fhp, SWITCH_FILE_DONE);
switch_set_flag_locked(fhp, SWITCH_FILE_DONE);
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(cmd, "truncate")) {
switch_core_file_truncate(fhp, 0);

View File

@ -592,14 +592,16 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
if (!cp->ready) {
continue;
}
switch_mutex_lock(cp->audio_mutex);
switch_mutex_lock(cp->audio_mutex);
if (switch_test_flag(cp->handle, SWITCH_FILE_OPEN)) {
if (source->has_video) {
switch_set_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO);
if (source->has_video && !switch_test_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO)) {
switch_set_flag_locked(cp->handle, SWITCH_FILE_FLAG_VIDEO);
} else {
switch_clear_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO);
if (switch_test_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO)) {
switch_clear_flag_locked(cp->handle, SWITCH_FILE_FLAG_VIDEO);
}
}
if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) {
@ -854,7 +856,7 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
if (!switch_core_has_video() ||
(switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) && !source->has_video && !source->blank_img && !source->cover_art && !source->banner_txt)) {
switch_clear_flag(handle, SWITCH_FILE_FLAG_VIDEO);
switch_clear_flag_locked(handle, SWITCH_FILE_FLAG_VIDEO);
}
context->source = source;
@ -888,9 +890,11 @@ static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
//pool = context->pool;
source = context->source;
context->ready = 0;
switch_mutex_lock(source->mutex);
switch_clear_flag_locked(handle, SWITCH_FILE_OPEN);
context->ready = 0;
for (cp = source->context_list; cp; cp = cp->next) {
if (cp == context) {
if (last) {

View File

@ -451,9 +451,9 @@ static switch_status_t next_file(switch_file_handle_t *handle)
handle->interval = context->fh.interval;
if (switch_test_flag((&context->fh), SWITCH_FILE_NATIVE)) {
switch_set_flag(handle, SWITCH_FILE_NATIVE);
switch_set_flag_locked(handle, SWITCH_FILE_NATIVE);
} else {
switch_clear_flag(handle, SWITCH_FILE_NATIVE);
switch_clear_flag_locked(handle, SWITCH_FILE_NATIVE);
}
return SWITCH_STATUS_SUCCESS;

View File

@ -347,9 +347,9 @@ switch_status_t FSSession::StreamInputCallback(switch_core_session_t *session, v
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(ret, "pause")) {
if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
switch_clear_flag(fh, SWITCH_FILE_PAUSE);
switch_clear_flag_locked(fh, SWITCH_FILE_PAUSE);
} else {
switch_set_flag(fh, SWITCH_FILE_PAUSE);
switch_set_flag_locked(fh, SWITCH_FILE_PAUSE);
}
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(ret, "truncate")) {
@ -416,9 +416,9 @@ switch_status_t FSSession::RecordInputCallback(switch_core_session_t *session, v
if (!strcasecmp(ret, "pause")) {
if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) {
switch_clear_flag(fh, SWITCH_FILE_PAUSE);
switch_clear_flag_locked(fh, SWITCH_FILE_PAUSE);
} else {
switch_set_flag(fh, SWITCH_FILE_PAUSE);
switch_set_flag_locked(fh, SWITCH_FILE_PAUSE);
}
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(ret, "restart")) {

View File

@ -80,6 +80,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
switch_set_flag(fh, SWITCH_FILE_FLAG_FREE_POOL);
}
switch_mutex_init(&fh->flag_mutex, SWITCH_MUTEX_NESTED, fh->memory_pool);
fh->mm.samplerate = 44100;
fh->mm.channels = 1;
fh->mm.keyint = 60;
@ -259,7 +261,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
fh->line = line;
if (switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO) && !fh->file_interface->file_read_video) {
switch_clear_flag(fh, SWITCH_FILE_FLAG_VIDEO);
switch_clear_flag_locked(fh, SWITCH_FILE_FLAG_VIDEO);
}
if (spool_path) {
@ -341,12 +343,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file,
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "File has %d channels, muxing to %d channel%s will occur.\n", fh->real_channels, fh->channels, fh->channels == 1 ? "" : "s");
}
switch_set_flag(fh, SWITCH_FILE_OPEN);
switch_set_flag_locked(fh, SWITCH_FILE_OPEN);
return status;
fail:
switch_clear_flag(fh, SWITCH_FILE_OPEN);
switch_clear_flag_locked(fh, SWITCH_FILE_OPEN);
if (fh->params) {
switch_event_destroy(&fh->params);
@ -387,7 +389,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh,
}
if (switch_test_flag(fh, SWITCH_FILE_DONE)) {
switch_clear_flag(fh, SWITCH_FILE_DONE);
switch_clear_flag_locked(fh, SWITCH_FILE_DONE);
*len = 0;
return SWITCH_STATUS_FALSE;
}
@ -410,7 +412,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh,
if (status != SWITCH_STATUS_SUCCESS || !rlen) {
switch_set_flag(fh, SWITCH_FILE_BUFFER_DONE);
switch_set_flag_locked(fh, SWITCH_FILE_BUFFER_DONE);
} else {
fh->samples_in += rlen;
if (fh->real_channels != fh->channels && !switch_test_flag(fh, SWITCH_FILE_NOMUX)) {
@ -425,7 +427,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh,
*len = asis ? rlen : rlen / 2 / fh->channels;
if (*len == 0) {
switch_set_flag(fh, SWITCH_FILE_DONE);
switch_set_flag_locked(fh, SWITCH_FILE_DONE);
goto top;
} else {
status = SWITCH_STATUS_SUCCESS;
@ -438,7 +440,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_read(switch_file_handle_t *fh,
}
if (status != SWITCH_STATUS_SUCCESS || !*len) {
switch_set_flag(fh, SWITCH_FILE_DONE);
switch_set_flag_locked(fh, SWITCH_FILE_DONE);
goto top;
}
@ -659,7 +661,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_seek(switch_file_handle_t *fh,
}
}
switch_set_flag(fh, SWITCH_FILE_SEEK);
switch_set_flag_locked(fh, SWITCH_FILE_SEEK);
status = fh->file_interface->file_seek(fh, cur_pos, samples, whence);
fh->offset_pos = *cur_pos;
@ -744,17 +746,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
return SWITCH_STATUS_FALSE;
}
if (fh->params) {
switch_event_destroy(&fh->params);
}
fh->samples_in = 0;
fh->max_samples = 0;
if (fh->buffer) {
switch_buffer_destroy(&fh->buffer);
}
if (fh->pre_buffer) {
if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
switch_size_t rlen, blen;
@ -777,9 +768,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
switch_buffer_destroy(&fh->pre_buffer);
}
switch_clear_flag(fh, SWITCH_FILE_OPEN);
switch_clear_flag_locked(fh, SWITCH_FILE_OPEN);
status = fh->file_interface->file_close(fh);
if (fh->params) {
switch_event_destroy(&fh->params);
}
fh->samples_in = 0;
fh->max_samples = 0;
if (fh->buffer) {
switch_buffer_destroy(&fh->buffer);
}
switch_resample_destroy(&fh->resampler);
if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
@ -807,6 +809,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
}
UNPROTECT_INTERFACE(fh->file_interface);
fh->file_interface = NULL;
return status;
}

View File

@ -3874,13 +3874,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_process_fh(switch_core_session_t *ses
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(cmd, "pause")) {
if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)) {
switch_clear_flag(fhp, SWITCH_FILE_PAUSE);
switch_clear_flag_locked(fhp, SWITCH_FILE_PAUSE);
} else {
switch_set_flag(fhp, SWITCH_FILE_PAUSE);
switch_set_flag_locked(fhp, SWITCH_FILE_PAUSE);
}
return SWITCH_STATUS_SUCCESS;
} else if (!strcasecmp(cmd, "stop")) {
switch_set_flag(fhp, SWITCH_FILE_DONE);
switch_set_flag_locked(fhp, SWITCH_FILE_DONE);
return SWITCH_STATUS_FALSE;
} else if (!strcasecmp(cmd, "truncate")) {
switch_core_file_truncate(fhp, 0);

View File

@ -2576,8 +2576,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t
out_file = switch_core_session_sprintf(session, "%s-out.%s", file, ext);
rh->in_fh.pre_buffer_datalen = rh->out_fh.pre_buffer_datalen = fh->pre_buffer_datalen;
channels = 1;
switch_set_flag(&rh->in_fh, SWITCH_FILE_NATIVE);
switch_set_flag(&rh->out_fh, SWITCH_FILE_NATIVE);
switch_set_flag_locked(&rh->in_fh, SWITCH_FILE_NATIVE);
switch_set_flag_locked(&rh->out_fh, SWITCH_FILE_NATIVE);
if (switch_core_file_open(&rh->in_fh, in_file, channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", in_file);

View File

@ -557,7 +557,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se
if (sample_start > 0) {
uint32_t pos = 0;
switch_core_file_seek(fh, &pos, sample_start, SEEK_SET);
switch_clear_flag(fh, SWITCH_FILE_SEEK);
switch_clear_flag_locked(fh, SWITCH_FILE_SEEK);
fh->samples = 0;
}
@ -1306,7 +1306,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
uint32_t pos = 0;
switch_core_file_seek(fh, &pos, 0, SEEK_SET);
switch_core_file_seek(fh, &pos, sample_start, SEEK_CUR);
switch_clear_flag(fh, SWITCH_FILE_SEEK);
switch_clear_flag_locked(fh, SWITCH_FILE_SEEK);
}
if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_TITLE, &p) == SWITCH_STATUS_SUCCESS) {
@ -1589,7 +1589,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) {
olen /= 2;
}
switch_set_flag(fh, SWITCH_FILE_BREAK_ON_CHANGE);
switch_set_flag_locked(fh, SWITCH_FILE_BREAK_ON_CHANGE);
if ((rstatus = switch_core_file_read(fh, abuf, &olen)) == SWITCH_STATUS_BREAK) {
continue;
@ -1651,7 +1651,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
if (switch_test_flag(fh, SWITCH_FILE_SEEK)) {
/* file position has changed flush the buffer */
switch_buffer_zero(fh->audio_buffer);
switch_clear_flag(fh, SWITCH_FILE_SEEK);
switch_clear_flag_locked(fh, SWITCH_FILE_SEEK);
}
@ -1733,11 +1733,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess
if (args && (args->read_frame_callback)) {
int ok = 1;
switch_set_flag(fh, SWITCH_FILE_CALLBACK);
switch_set_flag_locked(fh, SWITCH_FILE_CALLBACK);
if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
ok = 0;
}
switch_clear_flag(fh, SWITCH_FILE_CALLBACK);
switch_clear_flag_locked(fh, SWITCH_FILE_CALLBACK);
if (!ok) {
break;
}