Do not allow speech_channel_destroy() to return unless MRCP session has been terminated. Do not explicitly destroy mutexes, buffers, and condvars that are allocated off of pool.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16938 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Christopher Rienzo 2010-03-08 14:03:35 +00:00
parent c788145f57
commit 3b09933f31
1 changed files with 31 additions and 30 deletions

View File

@ -264,7 +264,7 @@ static switch_status_t audio_queue_destroy(audio_queue_t *queue);
*/ */
/* how long to wait for UniMRCP to process requests */ /* how long to wait for UniMRCP to process requests */
#define SPEECH_CHANNEL_TIMEOUT_USEC (10 * 1000000) #define SPEECH_CHANNEL_TIMEOUT_USEC (30 * 1000000)
/** /**
* Type of MRCP channel * Type of MRCP channel
@ -749,17 +749,6 @@ static switch_status_t audio_queue_destroy(audio_queue_t *queue)
if (zstr(name)) { if (zstr(name)) {
name = ""; name = "";
} }
if (queue->buffer) {
switch_buffer_destroy(&queue->buffer);
}
if (queue->mutex) {
switch_mutex_destroy(queue->mutex);
queue->mutex = NULL;
}
if (queue->cond) {
switch_thread_cond_destroy(queue->cond);
queue->cond = NULL;
}
#ifdef MOD_UNIMRCP_DEBUG_AUDIO_QUEUE #ifdef MOD_UNIMRCP_DEBUG_AUDIO_QUEUE
if (queue->file_read) { if (queue->file_read) {
switch_file_close(queue->file_read); switch_file_close(queue->file_read);
@ -834,27 +823,40 @@ static switch_status_t speech_channel_create(speech_channel_t ** schannel, const
* @return SWITCH_STATUS_SUCCESS * @return SWITCH_STATUS_SUCCESS
*/ */
static switch_status_t speech_channel_destroy(speech_channel_t *schannel) static switch_status_t speech_channel_destroy(speech_channel_t *schannel)
{ {
/* destroy the channel and session if not already done */ if (schannel) {
switch_mutex_lock(schannel->mutex); /* Terminate the MRCP session if not already done */
if (schannel->state != SPEECH_CHANNEL_CLOSED) { if (schannel->mutex) {
mrcp_application_session_terminate(schannel->unimrcp_session); switch_mutex_lock(schannel->mutex);
while (schannel->state != SPEECH_CHANNEL_CLOSED) { if (schannel->state != SPEECH_CHANNEL_CLOSED) {
if (switch_thread_cond_timedwait(schannel->cond, schannel->mutex, SPEECH_CHANNEL_TIMEOUT_USEC) == SWITCH_STATUS_TIMEOUT) { int warned = 0;
break; mrcp_application_session_terminate(schannel->unimrcp_session);
/* wait forever for session to terminate. Log WARNING if this starts taking too long */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "(%s) Waiting for MRCP session to terminate\n", schannel->name);
while (schannel->state != SPEECH_CHANNEL_CLOSED) {
if (switch_thread_cond_timedwait(schannel->cond, schannel->mutex, SPEECH_CHANNEL_TIMEOUT_USEC) == SWITCH_STATUS_TIMEOUT && !warned) {
warned = 1;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "(%s) MRCP session has not terminated after %d ms\n", schannel->name, SPEECH_CHANNEL_TIMEOUT_USEC / (1000));
}
}
} }
switch_mutex_unlock(schannel->mutex);
} }
if (schannel->state != SPEECH_CHANNEL_CLOSED) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "(%s) Failed to destroy channel. Continuing\n", schannel->name); /* It is now safe to clean up the speech channel */
} else { if (schannel->mutex) {
audio_queue_destroy(schannel->audio_queue); switch_mutex_lock(schannel->mutex);
schannel->audio_queue = NULL; }
audio_queue_destroy(schannel->audio_queue);
schannel->audio_queue = NULL;
if (schannel->params) {
switch_core_hash_destroy(&schannel->params);
}
if (schannel->mutex) {
switch_mutex_unlock(schannel->mutex);
} }
} }
if (schannel->params) {
switch_core_hash_destroy(&schannel->params);
}
switch_mutex_unlock(schannel->mutex);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
@ -3801,7 +3803,6 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_unimrcp_shutdown)
mrcp_client_destroy(globals.mrcp_client); mrcp_client_destroy(globals.mrcp_client);
globals.mrcp_client = 0; globals.mrcp_client = 0;
switch_mutex_destroy(globals.mutex);
switch_core_hash_destroy(&globals.profiles); switch_core_hash_destroy(&globals.profiles);
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;