Fix an issue where dynamic threads can get free'd, but still exist in the

dynamic thread list.
(closes issue #10392, patch from Mihai, with credit to his colleague, Pete)


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@78242 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Russell Bryant 18 years ago
parent ad13307328
commit 2e8439052f

@ -856,6 +856,9 @@ static const struct ast_channel_tech iax2_tech = {
.fixup = iax2_fixup,
};
/* WARNING: insert_idle_thread should only ever be called within the
* context of an iax2_process_thread() thread.
*/
static void insert_idle_thread(struct iax2_thread *thread)
{
if (thread->type == IAX_TYPE_DYNAMIC) {
@ -6384,11 +6387,13 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
if (errno != ECONNREFUSED && errno != EAGAIN)
ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
handle_error();
insert_idle_thread(thread);
thread->iostate = IAX_IOSTATE_IDLE;
signal_condition(&thread->lock, &thread->cond);
return 1;
}
if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
insert_idle_thread(thread);
thread->iostate = IAX_IOSTATE_IDLE;
signal_condition(&thread->lock, &thread->cond);
return 1;
}
@ -6411,7 +6416,8 @@ static int socket_read(int *id, int fd, short events, void *cbdata)
so queue it up for processing later. */
defer_full_frame(thread, cur);
AST_LIST_UNLOCK(&active_list);
insert_idle_thread(thread);
thread->iostate = IAX_IOSTATE_IDLE;
signal_condition(&thread->lock, &thread->cond);
return 1;
} else {
/* this thread is going to process this frame, so mark it */
@ -7896,13 +7902,27 @@ static void *iax2_process_thread(void *data)
/* Someone grabbed our thread *right* after we timed out.
* Wait for them to set us up with something to do and signal
* us to continue. */
ast_cond_wait(&thread->cond, &thread->lock);
tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = tv.tv_usec * 1000;
if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
{
ast_mutex_unlock(&thread->lock);
break;
}
}
} else {
ast_cond_wait(&thread->cond, &thread->lock);
}
/* Go back into our respective list */
put_into_idle = 1;
ast_mutex_unlock(&thread->lock);
if (thread->iostate == IAX_IOSTATE_IDLE)
continue;
/* Add ourselves to the active list now */
AST_LIST_LOCK(&active_list);
AST_LIST_INSERT_HEAD(&active_list, thread, list);
@ -7937,9 +7957,6 @@ static void *iax2_process_thread(void *data)
/* Make sure another frame didn't sneak in there after we thought we were done. */
handle_deferred_full_frames(thread);
/* Go back into our respective list */
put_into_idle = 1;
}
/* I am exiting here on my own volition, I need to clean up my own data structures

Loading…
Cancel
Save