From 02f69d36f4d2669a774962db148b01cf54ca2e5f Mon Sep 17 00:00:00 2001 From: Russell Bryant Date: Thu, 2 Aug 2007 18:04:43 +0000 Subject: [PATCH] Fix another race condition in the handling of dynamic threads. If the dynamic thread timed out waiting for something to do, but was acquired to perform an action immediately afterwords, then wait on the condition again to give the other thread a chance to finish setting up the data for what action this thread should perform. Otherwise, if it immediately continues, it will perform the wrong action. (reported on IRC by mihai, patch by me) (related to issue #10289) git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@77943 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 2dbc74f470..d21cf88274 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -7874,14 +7874,20 @@ static void *iax2_process_thread(void *data) 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); AST_LIST_LOCK(&dynamic_list); /* Account for the case where this thread is acquired *right* after a timeout */ if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) iaxdynamicthreadcount--; AST_LIST_UNLOCK(&dynamic_list); - if (t) + if (t) { + ast_mutex_unlock(&thread->lock); break; /* exiting the main loop */ + } + /* 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_timedwait(&thread->cond, &thread->lock, &ts); + ast_mutex_unlock(&thread->lock); } if (!t) ast_mutex_unlock(&thread->lock);